Posted By

wuori on 07/01/09


Tagged

FTP mosso rackspace


Versions (?)

FTP Image Transport to Rackspace Cloudfiles (fka Mosso)


 / Published in: PHP
 

URL: http://www.michaelwuori.com

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.

  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. }

Report this snippet  

You need to login to post a comment.