Return to Snippet

Revision: 15350
at July 1, 2009 11:01 by wuori


Initial Code
$date_from = '2008-12-13';
$date_to = '2009-12-31';
$domain = 'domain.com';
$mosso_id = 'mossoid';
$mosso_key = 'dfs243234fvasd2';
$mosso_container = 'domain.com-photos';

$ftp_user_name = 'asdf';
$ftp_user_pass = 'asdf';

$thumb_width = 140;
$thumb_height = 90;

$i = 0;	

$connection = mysql_connect('localhost', 'user', 'password') or die (mysql_error());
$db = mysql_select_db('database_name', $connection) or die (mysql_error());


// Step 3: Select 10 albums that don't have photos yet and transfer photos 

$get_empty_albums = mysql_query("
		SELECT tbox_albums.ID, count(tbox_albums_photos.ID) as photo_count 
		FROM tbox_albums 
		LEFT JOIN tbox_albums_photos 
		ON tbox_albums_photos.album = tbox_albums.ID 
		GROUP BY tbox_albums.ID
		ORDER BY tbox_albums_photos.album") 
	or die(mysql_error());
	
// Open a Connect with Mosso
include_once($_SERVER['DOCUMENT_ROOT'].'/public/ext/cloudfiles.php');
$auth = new CF_Authentication($mosso_id,$mosso_key);
$auth->authenticate();
$conn = new CF_Connection($auth);
$container = $conn->get_container($mosso_container);

// Open a Connect with FTP Server
$conn_id = ftp_connect('ftp.'.$domain); 
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass); 

// check connection
if ((!$conn_id) || (!$login_result)) exit('FTP Fail');

// change directory to albums content
if(!ftp_chdir($conn_id, "/public_html/_content/albums")) exit('couldnt find main directory');	

// run through empty album records
while($row=mysql_fetch_assoc($get_empty_albums)){
	if($row['ID'] && $row['photo_count'] < '1'){
		
		// init
		$this_album = $row['ID'];
	
		// Change PWD
		if($i>0) ftp_cdup($conn_id);
		if(!@ftp_chdir($conn_id, $row['ID'])) break;	

		// Read Directory and get full-size images
		$files = ftp_nlist($conn_id, ".");
		if(!count($files)) break;
		$file_paths = array();
		foreach($files as $file){
			// skip directories and thumbs
			if(strpos($file,'.jpg') && !strpos($file,'_t')){
				$file_paths[] = 'http://www.'.$domain.'/_content/albums/'.$this_album.'/'.$file;
			}
		}
		
		// Sort Numerically via cmp fxn
		usort($file_paths,'cmp');

		foreach($file_paths as $this_file){
		
			// get new filename while inserting photo record
			$iq = mysql_query("INSERT INTO tbox_albums_photos(album) VALUES ('".$this_album."')");
			if(!$iq) exit('photo insert failed');
			
			$photo_num = mysql_insert_id();
			$filename = $this_album.'_'.$photo_num;
			
			// Get file contents and save a tmp file
			$furl = getRemoteFile($this_file);
			$tmpfname = tempnam("/tmp", "FOO");
			$handle = fopen($tmpfname, "w");
			fwrite($handle, $furl);
			rewind($handle);
			
			// Image meta
			$src = getimagesize($tmpfname);
			
			// Create image resource
			$src_image = imagecreatefromjpeg($tmpfname);
			
			// Get crop points for thumbnails
			if ($src[0] > $src[1]) {
				$ratio = $src[0]/$thumb_width;
				$img_w = $thumb_width;
				$img_h = $src[1]/$ratio;					
				$dst_y = -(($img_h / 2) - ($thumb_height / 2));					
				if ($img_h < $thumb_height || $thumb_width == $thumb_height) {
					$ratio = $src[1]/$thumb_height;				
					$img_w = $src[0]/$ratio;
					$img_h = $thumb_height;
					$dst_y = 0;
				}
				$dst_x = -(($img_w / 2) - ($thumb_width / 2));
			} else {
				$ratio = $src[1]/$thumb_height;				
					$img_w = $src[0]/$ratio;						
					$img_h = $thumb_height;
					$dst_x = -(($img_w / 2) - ($thumb_width / 2));
				if ($img_w < $thumb_width || $thumb_width == $thumb_height) {
					$ratio = $src[0]/$thumb_width;
					$img_w = $thumb_width;
					$img_h = $src[1]/$ratio;
					$dst_x = 0;
				}
				$dst_y = -(($img_h / 2) - ($thumb_height / 2));
			}			

			// Create thumb canvas
			$dst_img_thumb = imagecreatetruecolor($thumb_width, $thumb_height);
			// Overlay cropped/resized image on thumb canvas
			@imagecopyresampled($dst_img_thumb, $src_image, $dst_x, $dst_y, 0, 0, $img_w, $img_h, $src[0], $src[1]);
			
			// Upload Big image to mosso
			$new_file = $container->create_object($filename.'.jpg');	
			$large = $new_file->load_from_filename($tmpfname);
			unlink($tmpfname);
			
			// Upload Thumb image to mosso
			$new_thumb_file = $container->create_object($filename.'_thumb.jpg');
			// -- no hard file to upload, create one
			// -- using output buffering and GD fxns
			ob_start();
			@ImageJPEG($dst_img_thumb,false,90);
			$image_buffer = ob_get_contents();
			ob_end_clean();
			@ImageDestroy($dst_img_thumb);
			$tmpfname = tempnam("/tmp", "FOO");
			$handle = fopen($tmpfname, "w");
			fwrite($handle, $image_buffer);
			rewind($handle);
			$thumb = $new_thumb_file->load_from_filename($tmpfname);
			unlink($tmpfname);
			
			if($large && $thumb){
				// Shit I might want to do to confirm
			}else{
				// If fail, delete data and go on to the net one
				// In this case, a missing photo isn't a big deal
				$photo_ID = mysql_query("DELETE FROM tbox_albums_photos WHERE ID = '".$photo_num."'");
			};
		};
	};
	$i++;
};
	
	
if($conn_id) ftp_close($conn_id); 			
exit('transferred photos');


// usort comparison
// so instead of 1,11-19,2,20 you get 1,2,3...
function cmp($a,$b){
	return (basename($a,'.jpg')<basename($b,'.jpg')) ? -1 : 1;
}

// get remote file contents like a mofo
function getRemoteFile($url){
   // get the host name and url path
   $parsedUrl = parse_url($url);
   $host = $parsedUrl['host'];
   if (isset($parsedUrl['path'])) {
      $path = $parsedUrl['path'];
   } else {
      // the url is pointing to the host like http://www.mysite.com
      $path = '/';
   }

   if (isset($parsedUrl['query'])) {
      $path .= '?' . $parsedUrl['query'];
   }

   if (isset($parsedUrl['port'])) {
      $port = $parsedUrl['port'];
   } else {
      // most sites use port 80
      $port = '80';
   }

   $timeout = 10;
   $response = '';

   // connect to the remote server
   $fp = @fsockopen($host, '80', $errno, $errstr, $timeout );

   if( !$fp ) {
      echo "Cannot retrieve $url";
   } else {
      // send the necessary headers to get the file
      fputs($fp, "GET $path HTTP/1.0
" .
                 "Host: $host
" .
                 "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
" .
                 "Accept: */*
" .
                 "Accept-Language: en-us,en;q=0.5
" .
                 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
" .
                 "Keep-Alive: 300
" .
                 "Connection: keep-alive
" .
                 "Referer: http://$host

");

      // retrieve the response from the remote server
      while ( $line = fread( $fp, 4096 ) ) {
         $response .= $line;
      }

      fclose( $fp );

      // strip the headers
      $pos      = strpos($response, "

");
      $response = substr($response, $pos + 4);
   }

   // return the file content
   return $response;
}

Initial URL
http://www.michaelwuori.com

Initial Description
This is a little script I wrote for transferring a lot of images (around 700,000) from a server (via FTP), generating a thumbnail and sending both images to the Rackspace Cloud (via ReST API).  

Since working with remote images as GD resources was something new to me, as well as using output-buffering to create files for RS from POST data, I wanted to share this to see if anyone had better, more efficient ideas for this type of transport.

Note: I used file transport instead of writing to an actual cloudfile object to avoid doing a checksum to see if all data was transported correctly, also because similar image functions (such as uploading via Facebook API) require an actual file as well.

Initial Title
FTP Image Transport to Rackspace Cloudfiles (fka Mosso)

Initial Tags


Initial Language
PHP