FTP Image Transport to Rackspace Cloudfiles (fka Mosso)


/ Published in: PHP
Save to your folder(s)

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.


Copy this code and paste it in your HTML
  1. $date_from = '2008-12-13';
  2. $date_to = '2009-12-31';
  3. $domain = 'domain.com';
  4. $mosso_id = 'mossoid';
  5. $mosso_key = 'dfs243234fvasd2';
  6. $mosso_container = 'domain.com-photos';
  7.  
  8. $ftp_user_name = 'asdf';
  9. $ftp_user_pass = 'asdf';
  10.  
  11. $thumb_width = 140;
  12. $thumb_height = 90;
  13.  
  14. $i = 0;
  15.  
  16. $connection = mysql_connect('localhost', 'user', 'password') or die (mysql_error());
  17. $db = mysql_select_db('database_name', $connection) or die (mysql_error());
  18.  
  19.  
  20. // Step 3: Select 10 albums that don't have photos yet and transfer photos
  21.  
  22. $get_empty_albums = mysql_query("
  23. SELECT tbox_albums.ID, count(tbox_albums_photos.ID) as photo_count
  24. FROM tbox_albums
  25. LEFT JOIN tbox_albums_photos
  26. ON tbox_albums_photos.album = tbox_albums.ID
  27. GROUP BY tbox_albums.ID
  28. ORDER BY tbox_albums_photos.album")
  29.  
  30. // Open a Connect with Mosso
  31. include_once($_SERVER['DOCUMENT_ROOT'].'/public/ext/cloudfiles.php');
  32. $auth = new CF_Authentication($mosso_id,$mosso_key);
  33. $auth->authenticate();
  34. $conn = new CF_Connection($auth);
  35. $container = $conn->get_container($mosso_container);
  36.  
  37. // Open a Connect with FTP Server
  38. $conn_id = ftp_connect('ftp.'.$domain);
  39. $login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
  40.  
  41. // check connection
  42. if ((!$conn_id) || (!$login_result)) exit('FTP Fail');
  43.  
  44. // change directory to albums content
  45. if(!ftp_chdir($conn_id, "/public_html/_content/albums")) exit('couldnt find main directory');
  46.  
  47. // run through empty album records
  48. while($row=mysql_fetch_assoc($get_empty_albums)){
  49. if($row['ID'] && $row['photo_count'] < '1'){
  50.  
  51. // init
  52. $this_album = $row['ID'];
  53.  
  54. // Change PWD
  55. if($i>0) ftp_cdup($conn_id);
  56. if(!@ftp_chdir($conn_id, $row['ID'])) break;
  57.  
  58. // Read Directory and get full-size images
  59. $files = ftp_nlist($conn_id, ".");
  60. if(!count($files)) break;
  61. $file_paths = array();
  62. foreach($files as $file){
  63. // skip directories and thumbs
  64. if(strpos($file,'.jpg') && !strpos($file,'_t')){
  65. $file_paths[] = 'http://www.'.$domain.'/_content/albums/'.$this_album.'/'.$file;
  66. }
  67. }
  68.  
  69. // Sort Numerically via cmp fxn
  70. usort($file_paths,'cmp');
  71.  
  72. foreach($file_paths as $this_file){
  73.  
  74. // get new filename while inserting photo record
  75. $iq = mysql_query("INSERT INTO tbox_albums_photos(album) VALUES ('".$this_album."')");
  76. if(!$iq) exit('photo insert failed');
  77.  
  78. $photo_num = mysql_insert_id();
  79. $filename = $this_album.'_'.$photo_num;
  80.  
  81. // Get file contents and save a tmp file
  82. $furl = getRemoteFile($this_file);
  83. $tmpfname = tempnam("/tmp", "FOO");
  84. $handle = fopen($tmpfname, "w");
  85. fwrite($handle, $furl);
  86. rewind($handle);
  87.  
  88. // Image meta
  89. $src = getimagesize($tmpfname);
  90.  
  91. // Create image resource
  92. $src_image = imagecreatefromjpeg($tmpfname);
  93.  
  94. // Get crop points for thumbnails
  95. if ($src[0] > $src[1]) {
  96. $ratio = $src[0]/$thumb_width;
  97. $img_w = $thumb_width;
  98. $img_h = $src[1]/$ratio;
  99. $dst_y = -(($img_h / 2) - ($thumb_height / 2));
  100. if ($img_h < $thumb_height || $thumb_width == $thumb_height) {
  101. $ratio = $src[1]/$thumb_height;
  102. $img_w = $src[0]/$ratio;
  103. $img_h = $thumb_height;
  104. $dst_y = 0;
  105. }
  106. $dst_x = -(($img_w / 2) - ($thumb_width / 2));
  107. } else {
  108. $ratio = $src[1]/$thumb_height;
  109. $img_w = $src[0]/$ratio;
  110. $img_h = $thumb_height;
  111. $dst_x = -(($img_w / 2) - ($thumb_width / 2));
  112. if ($img_w < $thumb_width || $thumb_width == $thumb_height) {
  113. $ratio = $src[0]/$thumb_width;
  114. $img_w = $thumb_width;
  115. $img_h = $src[1]/$ratio;
  116. $dst_x = 0;
  117. }
  118. $dst_y = -(($img_h / 2) - ($thumb_height / 2));
  119. }
  120.  
  121. // Create thumb canvas
  122. $dst_img_thumb = imagecreatetruecolor($thumb_width, $thumb_height);
  123. // Overlay cropped/resized image on thumb canvas
  124. @imagecopyresampled($dst_img_thumb, $src_image, $dst_x, $dst_y, 0, 0, $img_w, $img_h, $src[0], $src[1]);
  125.  
  126. // Upload Big image to mosso
  127. $new_file = $container->create_object($filename.'.jpg');
  128. $large = $new_file->load_from_filename($tmpfname);
  129. unlink($tmpfname);
  130.  
  131. // Upload Thumb image to mosso
  132. $new_thumb_file = $container->create_object($filename.'_thumb.jpg');
  133. // -- no hard file to upload, create one
  134. // -- using output buffering and GD fxns
  135. @ImageJPEG($dst_img_thumb,false,90);
  136. $image_buffer = ob_get_contents();
  137. @ImageDestroy($dst_img_thumb);
  138. $tmpfname = tempnam("/tmp", "FOO");
  139. $handle = fopen($tmpfname, "w");
  140. fwrite($handle, $image_buffer);
  141. rewind($handle);
  142. $thumb = $new_thumb_file->load_from_filename($tmpfname);
  143. unlink($tmpfname);
  144.  
  145. if($large && $thumb){
  146. // Shit I might want to do to confirm
  147. }else{
  148. // If fail, delete data and go on to the net one
  149. // In this case, a missing photo isn't a big deal
  150. $photo_ID = mysql_query("DELETE FROM tbox_albums_photos WHERE ID = '".$photo_num."'");
  151. };
  152. };
  153. };
  154. $i++;
  155. };
  156.  
  157.  
  158. if($conn_id) ftp_close($conn_id);
  159. exit('transferred photos');
  160.  
  161.  
  162. // usort comparison
  163. // so instead of 1,11-19,2,20 you get 1,2,3...
  164. function cmp($a,$b){
  165. return (basename($a,'.jpg')<basename($b,'.jpg')) ? -1 : 1;
  166. }
  167.  
  168. // get remote file contents like a mofo
  169. function getRemoteFile($url){
  170. // get the host name and url path
  171. $parsedUrl = parse_url($url);
  172. $host = $parsedUrl['host'];
  173. if (isset($parsedUrl['path'])) {
  174. $path = $parsedUrl['path'];
  175. } else {
  176. // the url is pointing to the host like http://www.mysite.com
  177. $path = '/';
  178. }
  179.  
  180. if (isset($parsedUrl['query'])) {
  181. $path .= '?' . $parsedUrl['query'];
  182. }
  183.  
  184. if (isset($parsedUrl['port'])) {
  185. $port = $parsedUrl['port'];
  186. } else {
  187. // most sites use port 80
  188. $port = '80';
  189. }
  190.  
  191. $timeout = 10;
  192. $response = '';
  193.  
  194. // connect to the remote server
  195. $fp = @fsockopen($host, '80', $errno, $errstr, $timeout );
  196.  
  197. if( !$fp ) {
  198. echo "Cannot retrieve $url";
  199. } else {
  200. // send the necessary headers to get the file
  201. fputs($fp, "GET $path HTTP/1.0
  202. " .
  203. "Host: $host
  204. " .
  205. "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
  206. " .
  207. "Accept: */*
  208. " .
  209. "Accept-Language: en-us,en;q=0.5
  210. " .
  211. "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
  212. " .
  213. "Keep-Alive: 300
  214. " .
  215. "Connection: keep-alive
  216. " .
  217. "Referer: http://$host
  218.  
  219. ");
  220.  
  221. // retrieve the response from the remote server
  222. while ( $line = fread( $fp, 4096 ) ) {
  223. $response .= $line;
  224. }
  225.  
  226. fclose( $fp );
  227.  
  228. // strip the headers
  229. $pos = strpos($response, "
  230.  
  231. ");
  232. $response = substr($response, $pos + 4);
  233. }
  234.  
  235. // return the file content
  236. return $response;
  237. }

URL: http://www.michaelwuori.com

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.