From 9563987a60159ba61afba6b55cf36a2f024c8abb Mon Sep 17 00:00:00 2001 From: Banana Date: Sun, 20 Aug 2017 21:20:42 +0200 Subject: [PATCH] first draft of the e-mail importer... --- documentation/email-importer.txt | 11 ++ documentation/features.txt | 4 +- documentation/requirements.txt | 2 +- webroot/config.default.php | 12 ++- webroot/job/email-import.php | 84 +++++++++++++++ webroot/job/error.log | 73 +++++++++++++ webroot/lib/simple-imap.class.php | 173 ++++++++++++++++++++++++++++++ 7 files changed, 356 insertions(+), 3 deletions(-) create mode 100644 documentation/email-importer.txt create mode 100644 webroot/job/email-import.php create mode 100644 webroot/job/error.log create mode 100644 webroot/lib/simple-imap.class.php diff --git a/documentation/email-importer.txt b/documentation/email-importer.txt new file mode 100644 index 0000000..6b813e9 --- /dev/null +++ b/documentation/email-importer.txt @@ -0,0 +1,11 @@ +Insipid has a feature to fetch new links from e-mails. +Those e-mails are read from a configured IMAP mailbox. + +You need to enable the imap functions within PHP and +have a IMAP mailbox on a SSL/TLS email server. + +Set the config variables in the config file. +Make sure you an individual marker string! +There is no "security" within this method. Only the special string you can define. +The new links will be hidden at first. You need to verify them before they are +visible in your list. \ No newline at end of file diff --git a/documentation/features.txt b/documentation/features.txt index f82acf7..7019f8c 100644 --- a/documentation/features.txt +++ b/documentation/features.txt @@ -5,4 +5,6 @@ Your data is your data. Bookmarks are put into categories and should have tags. -New links will be checked and tried to get as much as possible information automatically. \ No newline at end of file +New links will be checked and tried to get as much as possible information automatically. + +If you enable the email importer, emails contents will be automatically added to the database. \ No newline at end of file diff --git a/documentation/requirements.txt b/documentation/requirements.txt index 7476b11..c017eb6 100644 --- a/documentation/requirements.txt +++ b/documentation/requirements.txt @@ -1,3 +1,3 @@ -Apache (2 and up) with PHP extension +Apache (2 and up) with PHP extension (+imap if you us the email importer) PHP (5 and up) with MySQL extension -> mysqli; curl enabled MySQL database 5.6.x and up \ No newline at end of file diff --git a/webroot/config.default.php b/webroot/config.default.php index a5369e5..2328ca8 100644 --- a/webroot/config.default.php +++ b/webroot/config.default.php @@ -35,4 +35,14 @@ define('DB_PREFIX','insipid'); # a _ is added automatically as seperation # user config define('FRONTEND_USERNAME','luke'); -define('FRONTEND_PASSWORD','thefather'); \ No newline at end of file +define('FRONTEND_PASSWORD','father'); + +# settings for importing from e-mail +# SSL/TLS only +# imap +define('EMAIL_SERVER',''); +define('EMAIL_SERVER_USER',''); +define('EMAIL_SERVER_PASS',''); +define('EMAIL_SERVER_PORT',993); +define('EMAIL_SERVER_MAILBOX','INBOX'); # default INBOX +define('EMAIL_MARKER','to-insipid- '); \ No newline at end of file diff --git a/webroot/job/email-import.php b/webroot/job/email-import.php new file mode 100644 index 0000000..f599062 --- /dev/null +++ b/webroot/job/email-import.php @@ -0,0 +1,84 @@ + + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://www.gnu.org/licenses/gpl-3.0. + * + */ + +mb_http_output('UTF-8'); +mb_internal_encoding('UTF-8'); +ini_set('error_reporting',-1); // E_ALL & E_STRICT +# time settings +date_default_timezone_set('Europe/Berlin'); + +define('DEBUG',true); + +## check request +$_urlToParse = filter_var($_SERVER['QUERY_STRING'],FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW); +if(!empty($_urlToParse)) { + # see http://de2.php.net/manual/en/regexp.reference.unicode.php + if(preg_match('/[\p{C}\p{M}\p{Sc}\p{Sk}\p{So}\p{Zl}\p{Zp}]/u',$_urlToParse) === 1) { + die('Malformed request. Make sure you know what you are doing.'); + } +} + +## set the error reporting +ini_set('log_errors',true); +ini_set('error_log','error.log'); +if(DEBUG === true) { + ini_set('display_errors',true); +} +else { + ini_set('display_errors',false); +} + +require('../config.php'); +require('../lib/simple-imap.class.php'); + +## DB connection +mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); # throw exeptions +$DB = new mysqli(DB_HOST, DB_USERNAME,DB_PASSWORD, DB_NAME); +if ($DB->connect_errno) exit('Can not connect to MySQL Server'); +$DB->set_charset("utf8mb4"); +$DB->query("SET collation_connection = 'utf8mb4_bin'"); + +# the email reader +$EmailReader = new SimpleImap(); +try { + $EmailReader->connect(); + #if(DEBUG === true) {$EmailReader->mailboxStatus();} +} +catch (Exception $e) { + error_log('Email server connection failed: '.var_export($e->getMessage(),true)); +} + +try { + $EmailReader->process(); +} +catch (Exception $e) { + error_log('Can not process email messages: '.var_export($e->getMessage(),true)); +} + +$DB->close(); +# END \ No newline at end of file diff --git a/webroot/job/error.log b/webroot/job/error.log new file mode 100644 index 0000000..4174bee --- /dev/null +++ b/webroot/job/error.log @@ -0,0 +1,73 @@ +[20-Aug-2017 19:32:30 Europe/Berlin] PHP Warning: require(config.php): failed to open stream: No such file or directory in /home/banana/code/insipid/webroot/job/email-import.php on line 56 +[20-Aug-2017 19:32:30 Europe/Berlin] PHP Fatal error: require(): Failed opening required 'config.php' (include_path='.:/usr/share/php5:/usr/share/php') in /home/banana/code/insipid/webroot/job/email-import.php on line 56 +[20-Aug-2017 19:42:37 Europe/Berlin] PHP Notice: Undefined variable: EmailReader in /home/banana/code/insipid/webroot/job/email-import.php on line 66 +[20-Aug-2017 19:42:37 Europe/Berlin] PHP Fatal error: Class name must be a valid object or a string in /home/banana/code/insipid/webroot/job/email-import.php on line 66 +[20-Aug-2017 19:43:13 Europe/Berlin] PHP Fatal error: Class 'EmailReader' not found in /home/banana/code/insipid/webroot/job/email-import.php on line 67 +[20-Aug-2017 19:43:23 Europe/Berlin] Email server connection failed: 'Missing EMAIL_SERVER' +[20-Aug-2017 19:43:25 Europe/Berlin] Email server connection failed: 'Missing EMAIL_SERVER' +[20-Aug-2017 19:43:49 Europe/Berlin] Email server connection failed: 'Missing EMAIL_SERVER' +[20-Aug-2017 19:43:59 Europe/Berlin] Email server connection failed: 'Missing EMAIL_SERVER' +[20-Aug-2017 19:46:06 Europe/Berlin] Email server connection failed: 'Missing EMAIL_SERVER' +[20-Aug-2017 20:07:56 Europe/Berlin] PHP Fatal error: Call to undefined function imap_open() in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 51 +[20-Aug-2017 20:52:35 Europe/Berlin] PHP Fatal error: Uncaught Error: Cannot use object of type stdClass as array in /home/banana/code/insipid/webroot/lib/simple-imap.class.php:76 +Stack trace: +#0 /home/banana/code/insipid/webroot/job/email-import.php(83): SimpleImap->process() +#1 {main} + thrown in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 20:53:03 Europe/Berlin] PHP Fatal error: Uncaught Error: Cannot use object of type stdClass as array in /home/banana/code/insipid/webroot/lib/simple-imap.class.php:77 +Stack trace: +#0 /home/banana/code/insipid/webroot/job/email-import.php(83): SimpleImap->process() +#1 {main} + thrown in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 20:56:57 Europe/Berlin] PHP Parse error: syntax error, unexpected '=>' (T_DOUBLE_ARROW), expecting ',' or ')' in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 83 +[20-Aug-2017 21:01:58 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:01:59 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:00 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:00 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:31 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:02:32 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 76 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:14 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 +[20-Aug-2017 21:06:15 Europe/Berlin] PHP Notice: Trying to get property of non-object in /home/banana/code/insipid/webroot/lib/simple-imap.class.php on line 77 diff --git a/webroot/lib/simple-imap.class.php b/webroot/lib/simple-imap.class.php new file mode 100644 index 0000000..7ff2be9 --- /dev/null +++ b/webroot/lib/simple-imap.class.php @@ -0,0 +1,173 @@ +_connectionstring = '{'.$this->_server.':'.$this->_port.'/imap/ssl}'; + } + + function __destruct() { + imap_close($this->_connection); + } + + + + /** + * connect to the e-mail server + * with this code SSL/TLS only + * + * @see http://ca.php.net/manual/en/function.imap-open.php + */ + public function connect() { + + if(empty($this->_server)) { + throw new Exception('Missing EMAIL_SERVER'); + } + if(empty($this->_port)) { + throw new Exception('Missing EMAIL_SERVER_PORT'); + } + if(empty($this->_user)) { + throw new Exception('Missing EMAIL_SERVER_USER'); + } + + # create the connection + $this->_connection = imap_open($this->_connectionstring.$this->_mailbox, $this->_user, $this->_pass); + + if(!$this->_connection) { + throw new Exception('Failed IMAP connection: '.var_export(imap_last_error(),true)); + } + } + + /** + * process the given mailbox and check for the special messages + */ + function process() { + $messagecount = imap_num_msg($this->_connection); + + if($messagecount === false) { + throw new Exception('Can not read the messages in given mailbox'); + } + + $messages = array(); + + for($i = 1; $i <= $messagecount; $i++) { + $subject = ''; + + # first we check the header. + + # extract the subject.... + $headerinfo = imap_rfc822_parse_headers(imap_fetchheader($this->_connection, $i)); + $subjectArr = imap_mime_header_decode($headerinfo->subject); + foreach ($subjectArr as $el) { + $subject .= $el->text; + } + + if(!empty($subject)) { + # check the special stuff + $markerextract = substr($subject, 0, strlen(EMAIL_MARKER)); + if($markerextract == EMAIL_MARKER) { + # valid message + var_dump($subject); + } + } + + /* + $messages[] = array( + 'index' => $i, + 'header' => $headerinfo, + 'body' => imap_qprint(imap_body($this->_connection, $i)), + 'structure' => imap_fetchstructure($this->_connection, $i) + ); + */ + } + + # log messages processed to all messages + + #var_dump($messages); + } + + /** + * the the current stats about the mail connection and INBOX + * kinda debug only + * + * @see http://ca.php.net/manual/en/function.imap-status.php + */ + public function mailboxStatus() { + if($this->_connection !== false) { + $status = imap_status($this->_connection, $this->_connectionstring.$this->_mailbox, SA_ALL); + var_dump("messages ".$status->messages); + var_dump("recent ".$status->recent); + var_dump("unseen ".$status->unseen); + var_dump("uidnext ".$status->uidnext); + var_dump("uidvalidity ".$status->uidvalidity); + + $list = imap_getmailboxes($this->_connection, $this->_connectionstring, "*"); + if (is_array($list)) { + foreach ($list as $key => $val) { + echo "($key) "; + echo imap_utf7_decode($val->name) . ","; + echo "'" . $val->delimiter . "',"; + echo $val->attributes . "
\n"; + } + } else { + error_log("imap_getmailboxes failed: ".var_export(imap_last_error())); + } + } + } + + + + + // move the message to a new folder + function move($msg_index, $folder='INBOX.Processed') { + // move on server + imap_mail_move($this->_connection, $msg_index, $folder); + imap_expunge($this->_connection); + + // re-read the inbox + $this->inbox(); + } + + // get a specific message (1 = first email, 2 = second email, etc.) + function get($msg_index=NULL) { + if (count($this->_inbox) <= 0) { + return array(); + } + elseif ( ! is_null($msg_index) && isset($this->_inbox[$msg_index])) { + return $this->_inbox[$msg_index]; + } + + return $this->_inbox[0]; + } + + + + /** + * close the imap connection + */ + function close() { + imap_close($this->_connection); + } +} + +?> \ No newline at end of file -- 2.39.5