| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | #!/usr/bin/env php
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | <?php | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Laconica - a distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2008, Controlez-Vous, 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 | 
					
						
							|  |  |  |  * 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/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 23:05:23 -04:00
										 |  |  | # Abort if called from a web server
 | 
					
						
							|  |  |  | if (isset($_SERVER) && array_key_exists('REQUEST_METHOD', $_SERVER)) { | 
					
						
							|  |  |  | 	print "This script must be run from the command line\n"; | 
					
						
							|  |  |  | 	exit(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | define('INSTALLDIR', dirname(__FILE__)); | 
					
						
							|  |  |  | define('LACONICA', true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | require_once(INSTALLDIR . '/lib/common.php'); | 
					
						
							| 
									
										
										
										
											2008-06-26 03:07:03 -04:00
										 |  |  | require_once(INSTALLDIR . '/lib/jabber.php'); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | # This is kind of clunky; we create a class to call the global functions
 | 
					
						
							|  |  |  | # in jabber.php, which create a new XMPP class. A more elegant (?) solution
 | 
					
						
							|  |  |  | # might be to use make this a subclass of XMPP.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | class XMPPDaemon { | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-26 03:59:20 -04:00
										 |  |  | 	function XMPPDaemon($resource=NULL) { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 		static $attrs = array('server', 'port', 'user', 'password', 'host'); | 
					
						
							| 
									
										
										
										
											2008-06-22 23:09:30 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		foreach ($attrs as $attr) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 			$this->$attr = common_config('xmpp', $attr); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-06-26 03:59:20 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if ($resource) { | 
					
						
							|  |  |  | 			$this->resource = $resource; | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			$this->resource = common_config('xmpp', 'resource') . 'daemon'; | 
					
						
							| 
									
										
										
										
											2008-06-26 03:59:20 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		$this->log(LOG_INFO, "{$this->user}@{$this->server}/{$this->resource}"); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function connect() { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 		$connect_to = ($this->host) ? $this->host : $this->server; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->log(LOG_INFO, "Connecting to $connect_to on port $this->port"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		$this->conn = jabber_connect($this->resource); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 		if (!$this->conn) { | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return !$this->conn->disconnected; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	function handle() { | 
					
						
							|  |  |  | 		while(!$this->conn->disconnected) { | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 			$payloads = $this->conn->processUntil(array('message', 'presence', | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 														'end_stream', 'session_start')); | 
					
						
							|  |  |  | 			foreach($payloads as $event) { | 
					
						
							|  |  |  | 				$pl = $event[1]; | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 				$this->log(LOG_DEBUG, "Received '$event[0]': " . print_r($pl, TRUE)); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 				switch($event[0]) { | 
					
						
							|  |  |  | 				 case 'message': | 
					
						
							|  |  |  | 					$this->handle_message($pl); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				 case 'presence': | 
					
						
							|  |  |  | 					$this->handle_presence($pl); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				 case 'session_start': | 
					
						
							|  |  |  | 					$this->handle_session($pl); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-26 14:11:44 -04:00
										 |  |  | 	function get_user($from) { | 
					
						
							|  |  |  | 		$user = User::staticGet('jabber', jabber_normalize_jid($from)); | 
					
						
							|  |  |  | 		return $user; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function get_confirmation($from) { | 
					
						
							|  |  |  | 		$confirm = new Confirm_address(); | 
					
						
							|  |  |  | 		$confirm->address = $from; | 
					
						
							|  |  |  | 		$confirm->address_type = 'jabber'; | 
					
						
							|  |  |  | 		if ($confirm->find(TRUE)) { | 
					
						
							|  |  |  | 			return $confirm; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	function handle_message(&$pl) { | 
					
						
							| 
									
										
										
										
											2008-06-23 18:36:41 -04:00
										 |  |  | 		if ($pl['type'] != 'chat') { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (strlen($pl['body']) == 0) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-06-26 16:39:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		$from = jabber_normalize_jid($pl['from']); | 
					
						
							|  |  |  | 		$user = $this->get_user($from); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 		if (!$user) { | 
					
						
							| 
									
										
										
										
											2008-06-23 00:18:16 -04:00
										 |  |  | 			$this->log(LOG_WARNING, 'Message from unknown user ' . $from); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ($this->handle_command($user, $pl['body'])) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$this->add_notice($user, $pl); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	function handle_command($user, $body) { | 
					
						
							|  |  |  | 		# XXX: localise
 | 
					
						
							|  |  |  | 		switch(trim($body)) { | 
					
						
							|  |  |  | 		 case 'on': | 
					
						
							|  |  |  | 			$this->set_notify($user, true); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		 case 'off': | 
					
						
							|  |  |  | 			$this->set_notify($user, false); | 
					
						
							|  |  |  | 			return true; | 
					
						
							|  |  |  | 		 default: | 
					
						
							|  |  |  | 			return false; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 22:38:59 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function set_notify(&$user, $notify) { | 
					
						
							|  |  |  | 		$orig = clone($user); | 
					
						
							|  |  |  | 		$user->jabbernotify = $notify; | 
					
						
							|  |  |  | 		$result = $user->update($orig); | 
					
						
							|  |  |  | 		if (!$id) { | 
					
						
							|  |  |  | 			$last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 			$this->log(LOG_ERROR, | 
					
						
							| 
									
										
										
										
											2008-06-22 22:38:59 -04:00
										 |  |  | 					   'Could not set notify flag to ' . $notify . | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 					   ' for user ' . common_log_objstring($user) . | 
					
						
							| 
									
										
										
										
											2008-06-22 22:38:59 -04:00
										 |  |  | 					   ': ' . $last_error->message); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			$this->log(LOG_INFO, | 
					
						
							|  |  |  | 					   'User ' . $user->nickname . ' set notify flag to ' . $notify); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	function add_notice(&$user, &$pl) { | 
					
						
							|  |  |  | 		$notice = new Notice(); | 
					
						
							|  |  |  | 		$notice->profile_id = $user->id; | 
					
						
							|  |  |  | 		$notice->content = trim(substr($pl['body'], 0, 140)); | 
					
						
							|  |  |  | 		$notice->created = DB_DataObject_Cast::dateTime(); | 
					
						
							|  |  |  | 		$notice->query('BEGIN'); | 
					
						
							|  |  |  | 		$id = $notice->insert(); | 
					
						
							|  |  |  | 		if (!$id) { | 
					
						
							|  |  |  | 			$last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 			$this->log(LOG_ERROR, | 
					
						
							|  |  |  | 					   'Could not insert ' . common_log_objstring($notice) . | 
					
						
							|  |  |  | 					   ' for user ' . common_log_objstring($user) . | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 					   ': ' . $last_error->message); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		$orig = clone($notice); | 
					
						
							|  |  |  | 		$notice->uri = common_notice_uri($notice); | 
					
						
							|  |  |  | 		$result = $notice->update($orig); | 
					
						
							|  |  |  | 		if (!$result) { | 
					
						
							|  |  |  | 			$last_error = &PEAR::getStaticProperty('DB_DataObject','lastError'); | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 			$this->log(LOG_ERROR, | 
					
						
							|  |  |  | 					   'Could not add URI to ' . common_log_objstring($notice) . | 
					
						
							|  |  |  | 					   ' for user ' . common_log_objstring($user) . | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 					   ': ' . $last_error->message); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-06-26 03:12:13 -04:00
										 |  |  | 		$notice->query('COMMIT'); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 		common_broadcast_notice($notice); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:38:59 -04:00
										 |  |  | 		$this->log(LOG_INFO, | 
					
						
							|  |  |  | 				   'Added notice ' . $notice->id . ' from user ' . $user->nickname); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	function handle_presence(&$pl) { | 
					
						
							| 
									
										
										
										
											2008-06-23 20:15:23 -04:00
										 |  |  | 		$from = jabber_normalize_jid($pl['from']); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 		switch ($pl['type']) { | 
					
						
							|  |  |  | 			case 'subscribe': | 
					
						
							|  |  |  | 			    # We let anyone subscribe
 | 
					
						
							|  |  |  | 				$this->subscribed($from); | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 				$this->log(LOG_INFO, | 
					
						
							|  |  |  | 				   'Accepted subscription from ' . $from); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			case 'subscribed': | 
					
						
							|  |  |  | 			case 'unsubscribed': | 
					
						
							| 
									
										
										
										
											2008-06-26 14:11:44 -04:00
										 |  |  | 			case 'unsubscribe': | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 				$this->log(LOG_INFO, | 
					
						
							|  |  |  | 				   'Ignoring  "' . $pl['type'] . '" from ' . $from); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 				if (!$pl['type']) { | 
					
						
							|  |  |  | 					$user = User::staticGet('jabber', $from); | 
					
						
							|  |  |  | 					if (!$user) { | 
					
						
							|  |  |  | 						$this->log(LOG_WARNING, 'Message from unknown user ' . $from); | 
					
						
							|  |  |  | 						return; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					if ($user->updatefrompresence) { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 						$this->log(LOG_INFO, 'Updating ' . $user->nickname . | 
					
						
							|  |  |  | 											 ' status from presence.'); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 						$this->add_notice($user, $pl); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 23:02:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 	function log($level, $msg) { | 
					
						
							|  |  |  | 		common_log($level, 'XMPPDaemon('.$this->resource.'): '.$msg); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function subscribed($to) { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 		jabber_special_presence('subscribed', $to); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 	function set_status($status) { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 		$this->log(LOG_INFO, 'Setting status to "' . $status . '"'); | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 		jabber_send_presence($status); | 
					
						
							| 
									
										
										
										
											2008-06-26 02:46:46 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | $resource = ($argc > 1) ? $argv[1] : NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | $daemon = new XMPPDaemon($resource); | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 23:01:50 -04:00
										 |  |  | if ($daemon->connect()) { | 
					
						
							| 
									
										
										
										
											2008-06-26 11:03:36 -04:00
										 |  |  | 	$daemon->set_status("Send me a message to post a notice"); | 
					
						
							| 
									
										
										
										
											2008-06-22 23:01:50 -04:00
										 |  |  | 	$daemon->handle(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-06-26 11:12:02 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-22 22:27:10 -04:00
										 |  |  | ?>
 |