diff options
author | Craig Andrews <candrews@integralblue.com> | 2010-01-08 18:52:09 -0500 |
---|---|---|
committer | Craig Andrews <candrews@integralblue.com> | 2010-01-08 18:52:43 -0500 |
commit | 055f3fdddb998bfee1a6f6e61d1ca6df4b2fb740 (patch) | |
tree | 41698275bb5ef8f76e77e5a9b6a504c35ac6fe4b /plugins/Imap | |
parent | e22af049a8df3e120ea88387d013dedec8554c43 (diff) |
Add an IMAP daemon so StatusNet can process incoming user posts via catch-all mailbox (in addition to the pre-existing script alias method)
Diffstat (limited to 'plugins/Imap')
-rw-r--r-- | plugins/Imap/ImapPlugin.php | 85 | ||||
-rw-r--r-- | plugins/Imap/README | 32 | ||||
-rwxr-xr-x | plugins/Imap/imapdaemon.php | 147 |
3 files changed, 264 insertions, 0 deletions
diff --git a/plugins/Imap/ImapPlugin.php b/plugins/Imap/ImapPlugin.php new file mode 100644 index 000000000..034444222 --- /dev/null +++ b/plugins/Imap/ImapPlugin.php @@ -0,0 +1,85 @@ +<?php +/** + * StatusNet, the distributed open-source microblogging tool + * + * Plugin to add a StatusNet Facebook application + * + * 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 Plugin + * @package StatusNet + * @author Zach Copley <zach@status.net> + * @copyright 2009 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')) { + exit(1); +} + +/** + * IMAP plugin to allow StatusNet to grab incoming emails and handle them as new user posts + * + * @category Plugin + * @package StatusNet + * @author Craig Andrews <candrews@integralblue.com + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://status.net/ + */ +class ImapPlugin extends Plugin +{ + public $mailbox; + public $user; + public $password; + public $poll_frequency = 60; + public static $instances = array(); + public static $daemon_added = array(); + + function initialize(){ + if(!isset($this->mailbox)){ + throw new Exception("must specify a mailbox"); + } + if(!isset($this->user)){ + throw new Exception("must specify a user"); + } + if(!isset($this->password)){ + throw new Exception("must specify a password"); + } + if(!isset($this->poll_frequency)){ + throw new Exception("must specify a poll_frequency"); + } + + self::$instances[] = $this; + return true; + } + + function cleanup(){ + $index = array_search($this, self::$instances); + unset(self::$instances[$index]); + return true; + } + + function onGetValidDaemons($daemons) + { + if(! self::$daemon_added){ + array_push($daemons, INSTALLDIR . + '/plugins/Imap/imapdaemon.php'); + self::$daemon_added = true; + } + return true; + } +} diff --git a/plugins/Imap/README b/plugins/Imap/README new file mode 100644 index 000000000..640a411a8 --- /dev/null +++ b/plugins/Imap/README @@ -0,0 +1,32 @@ +The IMAP plugin allows for StatusNet to check a POP or IMAP mailbox for +incoming mail containing user posts. + +Installation +============ +addPlugin('imap', array( + 'mailbox' => '...', + 'user' => '...', + 'password' => '...' +)); +to the bottom of your config.php + +Also, make sure: +$config['mail']['domain'] = 'yourdomain.example.net'; +is set in your config.php + +Create a catch-all account for your domain, and use this account with this +plugin. Whenever a user sends a message to their personal notice posting +address, the message should end up in this mailbox, and then the plugin daemon +will pick it up and post the notice on the user's behalf. + +The daemon included with this plugin 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. + +Settings +======== +mailbox*: the mailbox specifier. + See http://www.php.net/manual/en/function.imap-open.php for details +user*: username to use when authenticating to the mailbox +password*: password to use when authenticating to the mailbox +poll_frequency: how often (in seconds) to check for new messages diff --git a/plugins/Imap/imapdaemon.php b/plugins/Imap/imapdaemon.php new file mode 100755 index 000000000..a45c603ce --- /dev/null +++ b/plugins/Imap/imapdaemon.php @@ -0,0 +1,147 @@ +#!/usr/bin/env php +<?php +/* + * 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 + * 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/>. + */ + +define('INSTALLDIR', realpath(dirname(__FILE__) . '/../..')); + +$shortoptions = 'fi::'; +$longoptions = array('id::', 'foreground'); + +$helptext = <<<END_OF_IMAP_HELP +Daemon script for receiving new notices from users via a mail box (IMAP, POP3, etc) + + -i --id Identity (default none) + -f --foreground Stay in the foreground (default background) + +END_OF_IMAP_HELP; + +require_once INSTALLDIR.'/scripts/commandline.inc'; + +require_once INSTALLDIR . '/lib/common.php'; +require_once INSTALLDIR . '/lib/daemon.php'; +require_once INSTALLDIR.'/lib/mailhandler.php'; + +class IMAPDaemon extends Daemon +{ + function __construct($resource=null, $daemonize=true, $attrs) + { + parent::__construct($daemonize); + + foreach ($attrs as $attr=>$value) + { + $this->$attr = $value; + } + + $this->log(LOG_INFO, "INITIALIZE IMAPDaemon {" . $this->name() . "}"); + } + + function name() + { + return strtolower('imapdaemon.'.$this->user.'.'.crc32($this->mailbox)); + } + + function run() + { + $this->connect(); + while(true) + { + if(imap_ping($this->conn) || $this->connect()) + { + $this->check_mailbox(); + } + sleep($this->poll_frequency); + } + } + + function check_mailbox() + { + $count = imap_num_msg($this->conn); + $this->log(LOG_INFO, "Found $count messages"); + if($count > 0){ + $handler = new IMAPMailHandler(); + for($i=1; $i <= $count; $i++) + { + $rawmessage = imap_fetchheader($this->conn, $count, FT_PREFETCHTEXT) . imap_body($this->conn, $i); + $handler->handle_message($rawmessage); + imap_delete($this->conn, $i); + } + imap_expunge($this->conn); + $this->log(LOG_INFO, "Finished processing messages"); + } + } + + function log($level, $msg) + { + $text = $this->name() . ': '.$msg; + common_log($level, $text); + if (!$this->daemonize) + { + $line = common_log_line($level, $text); + echo $line; + echo "\n"; + } + } + + function connect() + { + $this->conn = imap_open($this->mailbox, $this->user, $this->password); + if($this->conn){ + $this->log(LOG_INFO, "Connected"); + return true; + }else{ + $this->log(LOG_INFO, "Failed to connect: " . imap_last_error()); + return false; + } + } +} + +class IMAPMailHandler extends MailHandler +{ + function error($from, $msg) + { + $this->log(LOG_INFO, "Error: $from $msg"); + $headers['To'] = $from; + $headers['Subject'] = "Error"; + + return mail_send(array($from), $headers, $msg); + } +} + +if (have_option('i', 'id')) { + $id = get_option_value('i', 'id'); +} else if (count($args) > 0) { + $id = $args[0]; +} else { + $id = null; +} + +$foreground = have_option('f', 'foreground'); + +foreach(ImapPlugin::$instances as $pluginInstance){ + + $daemon = new IMAPDaemon($id, !$foreground, array( + 'mailbox' => $pluginInstance->mailbox, + 'user' => $pluginInstance->user, + 'password' => $pluginInstance->password, + 'poll_frequency' => $pluginInstance->poll_frequency + )); + + $daemon->runOnce(); + +} |