Location: PHPKode > projects > KMB - KwentMailBlogger > kmb045.php
<?
/*************************************************************************************
 *	KMB - KwentMailBlogger
 *	V 0.1; 2004-10-30; (c) ACW (hide@address.com)
 *  V 0.2; 2004-11-03; (c) ACW (hide@address.com)
 *  V 0.3; 2004-11-07; (c) ACW (hide@address.com)
 *  V 0.4; 2004-12-11; (c) ACW (hide@address.com)
 *	V 0.45;2005-01-11; (c) ACW (hide@address.com)
 *************************************************************************************/
/* Rev. History
 * V 0.4:	arbitrary order of mime parts, escape single quotes, catch invalid jpegs
 *			before trying to resize them, handle mails with empty message-id
 * V 0.45:  added stripfoot(see below); enable inline images
 *************************************************************************************/

/*************************************************************************************
 *	Disclaimer/License:
 *	Did this for my personal fun. Don't blame me for anything.
 *	Licensed under MLL (My Little License):
 *		MLL:	Use it for free if you like it.
 *				Modify it, get rich with it if you've got a chance to.
 *				Acknowledge me visual if you think it's worth it.
 *				Keep this disclaimer in the source.
 *	Feedback:
 *	- welcome at hide@address.com
 *************************************************************************************/

/*************************************************************************************
 *	Purpose:
 *	Having a mobile phone with a built in cam and email capability?
 *	Want to publish your thoughts and images from the top of the mountain you just
 *  climbed instantly to your website?
 *	Try KMB, my little MailBlogger Utility.
 *	It connects to a certain mailaccount, grabs Emails with a certain Subject, by
 *  which it identifies regular entries.
 *	It extracts the text and attached images of a certain kind (see below) and saves
 *	the text and the original images to a database and the filesystem respectively.
 *	It resizes the images to a standard size chosen.
 *	It also rotates the images if necessary.
 *	It keeps the original(rotated) one as well as the resized to allow a preview 
 *	and a full view.
 *	Have fun
 *************************************************************************************/

/*************************************************************************************
 *	Requirements:
 *	- PHP 4.something I suppose
 *	- compiled with IMAP & GD support
 *  - a POP3 or IMAP capable mailaccount
 *************************************************************************************/

/*************************************************************************************
 *	Usage:
 *	- Create a mailaccount fulfilling the requirements stated above
 *	- Create a database table using the sql script found below
 *	- Create a directory for the images accessible by php
 *	- Choose if you want the script to be run standalone or included into your portal
 *	- Run it or include it wherever
 *	Posting:
 *	- Send an email to the Blog Account having the appropriate subject defined below
 *  - Attach images to your mail (preferrably jpgs, since they're known to work)
 *	- If you need your images to be rotated, add >90, >-90, or >180 to the subject
 *	  all(!!) images of that mail will then be rotated(90 is in degrees and clockwise)
 *	- mails having a subject other than the one defined are being deleted!!!
 *************************************************************************************/

/*************************************************************************************
 *	Limitations:
 *	- a lot ;-)
 *	- images other than jpg-likes are not resized and rotated
 *	- I suppose there are decoding issues with 'strange' encodings
 *	- Deletion of processed mails is not guaranteed (POP3 non-support of Mailflags?!)
 *	- (so have a look at your mail account from time to time)
 *	- no editing of posts other than via db-client tool
 *************************************************************************************/


/*************************************************************************************
 *	Configuration:
 *	set the following parameters to your needs; xxxx needs to be replaced
 *************************************************************************************/
 
// run this script standalone? (or include it elsewhere)
   $blogstandalone = false;		//true|false
// consider emails having a certain Subject only; simple security measure
   $SubjectCode = "xxxx";

// define a directory where attached images are stored; php should have read and 
// write access to it
   $imgDir = "./xxx/xxx/";

// set the timezone of your blog   
   $blogtimezone = +1;

// POP3 data of the account where blogmails are sent to; 110 is the POP3 port number
// to change this to imap, see the php documentation for "imap_open(...)"
   $ServerName = "{mysite.com/pop3:110}INBOX";   
   $UserName = "xxxxxxxxx";
   $PassWord = "xxxxxxxxx";
   
// define allowed attachment types; Case sensitive!!
// NOTE: if you define for example php here, someone can mail you a php-script and
// execute it; this may be very useful, but it may be extremly harmful too.
   $atttypes = "jpeg|jpg|png|gif|JPG|JPEG";

// some providers attach annoying footers; if they start with a certain string, we
// can strip them
   $stripfoot = "----";
   
// images received will be resized (needs PHP with GD support)
// !! so far only jpg, jpeg, JPG & JPEG!!
   $forcedwidth  = "300"; //width
   $forcedheight = "200"; //height
   $imgcomp      = "0";   // 0...best quality, 100...most compressed


// database connection
   $DatabaseName = "xxxxxxxx";
   $DbHostName   = "xxxxxxxx";
   $DbUserName   = "xxxxxxxx";
   $DbPassWord   = "xxxxxxxx";
   $DbBlogTab    = "xxxxxxxx";
   
// sql-script to create the table 'blogtab'; run it in your db-client, e.g. mysqladmin
/*
#
# Table structure for table 'XXXXXXXXXX'
#

CREATE TABLE `XXXXXXXXXX` (
  `blid` int(8) unsigned zerofill NOT NULL auto_increment,
  `origuid` varchar(64) default NULL,
  `bldate` datetime default '0000-00-00 00:00:00',
  `bltxt` text,
  `blimg` varchar(30) default NULL,
  PRIMARY KEY  (`blid`)
) TYPE=MyISAM;
*/

/*	END OF CONFIGURATION ***************************************************************/


// some functions  -------------------------------------------
   function get_mime_type(&$structure) {
   	$primary_mime_type = array("TEXT", "MULTIPART","MESSAGE", "APPLICATION", "AUDIO","IMAGE", "VIDEO", "OTHER");
   	if($structure->subtype) {
   	return $primary_mime_type[(int) $structure->type] . '/' .$structure->subtype;
   	}
   	return "TEXT/PLAIN";
   }
   function get_part($stream, $msg_number, $mime_type, $structure = false,$part_number    = false) {
   
   	if(!$structure) {
   		$structure = imap_fetchstructure($stream, $msg_number);
   	}
   	if($structure) {
   		if($mime_type == get_mime_type($structure)) {
   			if(!$part_number) {
   				$part_number = "1";
   			}
   			$text = imap_fetchbody($stream, $msg_number, $part_number);
   			if($structure->encoding == 3) {
   				return imap_base64($text);
   			} else if($structure->encoding == 4) {
   				return imap_qprint($text);
   			} else {
   			return $text;
   			}
   		}
   
		if($structure->type == 1) /* multipart */ {
   			while(list($index, $sub_structure) = each($structure->parts)) {
   				if($part_number) {
   					$prefix = $part_number . '.';
   				}
   				$data = get_part($stream, $msg_number, $mime_type, $sub_structure,$prefix .    ($index + 1));
   				if($data) {
   					return $data;
   				}
   			}
   		}
   	}
   	return false;
   }
   
   function write_to_fs($fileContent, $fileName, $imgDir, $angle) {
    global $forcedwidth, $forcedheight, $imgcomp; 

//	create unique filename
	$ext = explode(".", $fileName);
    $nfn = "i" . substr(md5(uniqid(rand())),0, 15) . '.' . $ext[1];
//	save file to file system   	    
    $ih = fopen($imgDir . $nfn, "w");
//    $fileContent = imap_base64($fileContent);
    $fileContent = base64_decode($fileContent);

//	fputs($ih, imap_base64($fileContent), strlen(imap_base64($fileContent)));
	fputs($ih, $fileContent, strlen($fileContent));
	fclose($ih);
	$rfn = $nfn;
	
	$sourcefile   = $imgDir . $nfn;
//	rotate file
	$nnfn = $nfn;
	if($angle == "90" || $angle == "-90" || $angle == "180") {
		$xfn = ereg_replace("^i", "x", $nfn);
		$rotfile = $imgDir . $xfn;		
		if ($rot = rotateimage($sourcefile, $rotfile, $angle)) {
			$nnfn	 = $xfn;
			$sourcefile = $rotfile;
			$rfn = $xfn;
		}
	}
//	resize file (either the original oder the rotated one)
	$dfn 		  = ereg_replace("^(x|i)", "r", $nnfn);
	$destfile	  = $imgDir . $dfn;
	if($ext[1]=="jpg" || $ext[1]=="jpeg" || $ext[1]=="JPG" || $ext[1]=="JPEG") {
		if($res = resampimagejpg ($forcedwidth, $forcedheight, $sourcefile, $destfile, $imgcomp)){
			$rfn = $dfn;
		}
	}
   	return $rfn;
   }

   function write_to_db($msgBody, $fn, $date, $origuid) {
		global $blogtimezone, $DbBlogTab;

//      convert date
		$tdate = strtotime($date); //convert to timestamp
		$ndate = gmdate("Y-m-d H:i", $tdate + 3600*($blogtimezone)); //format date from timestamp
//      save entry to db
    	$blog_ins = "INSERT INTO " . $DbBlogTab . "(blid, origuid, bldate, bltxt, blimg) VALUES ('', '$origuid', '$ndate', '$msgBody', '$fn')";
        $bl_res   = mysql_query($blog_ins);
        if ($bl_res) {
        	return true;
        }
		return false;
   }
   
   function resampimagejpg($forcedwidth, $forcedheight, $sourcefile, $destfile, $imgcomp) {
   
   $g_imgcomp=100-$imgcomp;
   $g_srcfile=$sourcefile;
   $g_dstfile=$destfile;
   $g_fw=$forcedwidth;
   $g_fh=$forcedheight;

   if(file_exists($g_srcfile)) {
       $g_is=getimagesize($g_srcfile);
       if($g_is[0] > $g_fw || $g_is[1] > $g_fh) {
       		if(($g_is[0]-$g_fw)>=($g_is[1]-$g_fh)) {
       		    $g_iw=$g_fw;
       		    $g_ih=($g_fw/$g_is[0])*$g_is[1];
       		}
       		else {
       		    $g_ih=$g_fh;
       		    $g_iw=($g_ih/$g_is[1])*$g_is[0];    
       		}
       		if ($img_src=@imagecreatefromjpeg($g_srcfile))
       		{
       			$img_dst=imagecreatetruecolor($g_iw,$g_ih);
       			imagecopyresampled($img_dst, $img_src, 0, 0, 0, 0, $g_iw, $g_ih, $g_is[0], $g_is[1]);
       			imagejpeg($img_dst, $g_dstfile, $g_imgcomp);
       			imagedestroy($img_dst);
       			return true;
       		} else { return false; }
       }
       else
       		return false;
   }
   else
   		return false;

   }
   
   function rotateimage($sourcefile, $destfile, $angle) {
//	rotation is clockwise!!
   	$img_src = imagecreatefromjpeg($sourcefile);
    $g_is=getimagesize($sourcefile);
    if ($angle == 90 || $angle == -90) {
	    $img_dst=imagecreatetruecolor($g_is[1],$g_is[0]);
	    $nw = $g_is[1];
	    $nh = $g_is[0];
	}
	else {	// its 180 or 360
		$img_dst=imagecreatetruecolor($g_is[0],$g_is[1]);
		$nw = $g_is[0];
		$nh = $g_is[1];
	}

   	$rotate = imagerotate($img_src, 360-$angle, 0);
    imagecopyresampled($img_dst, $rotate, 0, 0, 0, 0, $nw, $nh, $nw, $nh);
   	imagejpeg($img_dst, $destfile);
    imagedestroy($img_dst);
   	return true;

   }

   
   function check_msgid_new($msgid) {
   		global $DbBlogTab;
   		$mquery = "SELECT COUNT(*) AS moid FROM " . $DbBlogTab . " WHERE origuid = '$msgid'";
   		$mres   = mysql_query($mquery);
   		$moid = true;
		if($tmoid = mysql_result($mres, "0", "moid")) {
				$moid = false;
    	}
    	return $moid;
   }

// no more functions ----------------------------------------


   $attregexp = "(.(" . $atttypes . "))$";

   mysql_connect("$DbHostName", "$DbUserName", "$DbPassWord");
   mysql_select_db("$DatabaseName") or die ("Unable to connect to SQL Server");
   
   if ( $mbox = imap_open($ServerName, $UserName,$PassWord, CL_EXPUNGE) ){  
     if ($hdr = imap_check($mbox)) { 
	   	$msgCount = $hdr->Nmsgs;
	   	if ($msgCount > 0) { 
   			$MN=$msgCount;
   			$overview=imap_fetch_overview($mbox,"1:$MN",FT_UID);   			   			
   			$size=sizeof($overview);
      
   			for($i=0;$i<=$size-1;$i++){ 
   				$val=$overview[$i];
				$msgno=$val->msgno;
				$from=$val->from;
  				$date=$val->date;
  	$msgid = substr(md5($from . $date . $val->message_id),0, 15);		

				$subj=$val->subject; 
				$subj1 = imap_mime_header_decode($subj);  //decode 8859 subject
				$subj2 = explode(">", $subj1[0]->text);	  // see if we need to rotate
				$angle = '';
				if (isset($subj2[1])) {
					$angle = $subj2[1];
				}
				$recent = $val->recent;
				$flagged = $val->flagged;
   				$seen=$val->seen;
   				
	   			$from = ereg_replace("\"","",$from);
      			$uid = $val->uid;
      			
				if ($subj2[0] == $SubjectCode && check_msgid_new($msgid)) {
//					consider $seen??				
// 					get text body
   					$dataTxt = get_part($mbox, $msgno, "TEXT/PLAIN");
   					$msgBody = ereg_replace("\n","<br>",$dataTxt);
//                   
   					$msgBody = ereg_replace("(<br>[^a-zA-Z0-9]*)+$", '', $msgBody); 
					//multiple <br>'s at the end into one

					// replace footers
					if ($stripfoot != "") {
						$msgBody = ereg_replace($stripfoot . ".*", '', $msgBody);
					}

					$msgBody = ereg_replace("'", "&#039;", $msgBody); // replace single quotes

					$mailformat = "text";

//					enter the textpart into the database   					
   					$db = write_to_db($msgBody, '', $date, $msgid);

//					get attachments if any
   					$struct = imap_fetchstructure($mbox,$msgno);
   					$structpart = $struct->parts;		
   					$contentParts = count($struct->parts);
   
   					if ($contentParts >= 2) { 
						for ($j=1;$j<=$contentParts;$j++) {
   							$att[$j-1] = imap_bodystruct($mbox,$msgno,$j);
   						}
   						for ($k=0;$k<sizeof($att);$k++) {
   							if ($att[$k]->parameters[0]->value == "us-ascii" || $att[$k]->parameters[0]->value    == "US-ASCII") {
 //								accept only certain image types (Case sensitive!!)------  								
  								if (ereg($attregexp, $att[$k]->parameters[1]->value) || ereg($attregexp, 'x' . $structpart[$k]->subtype)) {
   									$fileContent = imap_fetchbody($mbox,$msgno,$k+1);
 									$fileName	 = $att[$k]->parameters[1]->value;
 									 //	if filename is empty set it to a temporary using the mime subtype as fileext 									
									 if ($fileName == "") { $fileName = "temp." . $structpart[$k]->subtype; }
 //									write file to file system & record to db
 									$new_fileName = write_to_fs($fileContent, $fileName, $imgDir, $angle);
 									$db = write_to_db($msgBody, $new_fileName, $date, $msgid);
 									if ($db) {
 										$status = imap_clearflag_full ($mbox, imap_uid($mbox,$msgno), "\\SEEN", SE_UID);
 									}
   								}
   							} 
   							elseif ($att[$k]->parameters[0]->value != "iso-8859-1" &&    $att[$k]->parameters[0]->value != "ISO-8859-1") {
 //								accept only certain image types (Case sensitive!!)------  								
 								if (ereg($attregexp, $att[$k]->parameters[1]->value) || ereg($attregexp, 'x' . $structpart[$k]->subtype)) {
   									$fileContent = imap_fetchbody($mbox,$msgno,$k+1);
									$fileName	 = $att[$k]->parameters[1]->value;
 //									if filename is empty set it to a temporary using the mime subtype as fileext 									
  									if ($fileName == "") { $fileName = "temp." . $structpart[$k]->subtype; }
 //									write file to file system & record to db
							 		$new_fileName = write_to_fs($fileContent, $fileName, $imgDir, $angle);
 									$db = write_to_db($msgBody, $new_fileName, $date, $msgid);
 									if ($db) {
 										$status = imap_clearflag_full ($mbox, imap_uid($mbox,$msgno), "\\SEEN", SE_UID);
 									}
   								}
   							}
   						}
   					}
   					else {
   						if ($db) {
							$status = imap_clearflag_full ($mbox, imap_uid($mbox,$msgno), "\\SEEN", SE_UID);
						}
					}
				}   
   				else {
  					$status = imap_setflag_full ($mbox, $msgno, "\\Deleted");
   				}
			}
		}
	 }
   	 imap_close($mbox);
   }

// now we output the whole stuff

$show_query = "SELECT * FROM " . $DbBlogTab . " order by blid desc";
$show_res   = mysql_query($show_query);
$oldoid = '';

if ($standalone) {
?>
	<HTML><HEAD><TITLE>MailBlogger by ACW</TITLE>
				<script type="text/javascript">
			function popitup(url, name, width, height)
			{
				var scrstr='';
				if(width>=800 || height >=600) { width=800; height=600; scrstr=',scrollbars=yes,resizable=yes'; } 
				var popsize = 'height=' + height + ',width='+width+scrstr;
				window.open(url,name,popsize);
				return false;
		}
	
		</HEAD>
		<BODY>
<?
}

echo '<CENTER><I><B>My Moblog</B></I></CENTER><BR><BR>';

while ($drec = mysql_fetch_array ($show_res)) {
	$sep = "<BR>";
	if ($drec["origuid"] !=  $oldoid ) {
		echo '<B>' . date("Y/m/d H:i", strtotime($drec["bldate"])) . '</B>' . '<BR>';
		echo '<I>' . $drec["bltxt"] . '</I>';
		$oldoid = $drec["origuid"];
		$sep = "<BR><BR>";
	}
	if (strlen($drec["blimg"]) > 0) {
		$oimg = ereg_replace("r", "x", $drec["blimg"]);
	    if(!file_exists($imgDir . $oimg)) {
	    	$oimg = ereg_replace("x", "i", $oimg);
	    }
		$isiz = getimagesize($imgDir . $oimg);
		$wiwi = $isiz[0];
		$wihe = $isiz[1];	
		echo '<BR><A HREF="#" onclick="popitup(\'xxxx.php?img='.$oimg.'\', \'Details\', \''.$wiwi.'\', \''.$wihe.'\'); ">';
// create xxx.php to show the full image!!!
	   	echo '<IMG SRC="' . $imgDir . $drec["blimg"] . '" border="0"></A>';
	}
	echo $sep;
}
if ($standalone) {
	echo '</BODY></HTML>';
}
?>
















Return current item: KMB - KwentMailBlogger