Search code examples
phpfile-uploadcurlrackspace-cloudrackspace

Faster Rackspace cloud upload


I have used to the Rackspace API to upload files to the RackSpace cloud. But this method seems to be a little on the slow side. Is there a better or faster way to upload a file to the cloud(curl, http adapters, etc)?

I am currently uploading with PHP and using the provided API.


Solution

  • Here is my solution how to make it fast:

    I'm uploading only missing files using simple PHP script below. Thanks to it I do it in just one click and in just a few seconds.

    PHP source code:

    function UploadMissingFilesToRackFileCDN($file_paths_to_upload, $b_force_upload = false)
    {
        include_once("cloudfiles.php");
    
        // Connect to Rackspace
        $username = cloudfile_username; // username
        echo "Connecting to CDN..." . date("H:i:s") . "<br>"; ob_flush();
        $key = cloudfile_api_key; // api key
        $auth = new CF_Authentication($username, $key);
        $auth->authenticate();
        $conn = new CF_Connection($auth);
        echo "&nbsp;&nbsp;&nbsp;&nbsp;Connected!" . date("H:i:s") . "<br>"; ob_flush();
    
        // Get the container we want to use
        $container_name = 'vladonai';//'test_container';
        echo "Obtaining container $container_name..." . date("H:i:s") . "<br>"; ob_flush();
        $container = $conn->get_container($container_name);
        echo "&nbsp;&nbsp;&nbsp;&nbsp;The container is obtained." . date("H:i:s") . "<br>"; ob_flush();
    
        if (!$b_force_upload)
        {
            echo "Receiving container objects list..." . date("H:i:s") . "<br>"; ob_flush();
            $existing_object_names = $container->list_objects();
            $existing_files_count = count($existing_object_names);
            echo "&nbsp;&nbsp;&nbsp;&nbsp;Objects list obtained: $existing_files_count." . date("H:i:s") . "<br>"; ob_flush();
            $existing_object_names_text .= "\r\n";
            foreach ($existing_object_names as $obj_name)
            {
                $existing_object_names_text .= $obj_name . "\r\n";
            } 
        }
    
        // upload files to Rackspace
        $uploaded_file_n = 0;
        $skipped_file_n = 0;
        $errors_count = 0;
        foreach ($file_paths_to_upload as $localfile_path => $file_info)
        {
            $filename = basename($localfile_path);
    
            if (!file_exists($localfile_path))
            {
                echo "<font color=red>Error! File $localfile_path doesn't exists!</font>" . date("H:i:s") . "<br>"; ob_flush();
                $errors_count ++;
            } else
            if (is_dir($localfile_path))
            {
                //simply skip it
            } else
            if (strpos($existing_object_names_text, "\r\n" . $filename . "\r\n") !== false)
            {
                //file is already uploaded to CDN (at least file name is present there). Would be good to have date/size checked, but CDN api has no such feature
                //echo "<font color=gray>Skipped file $localfile_path - it already exists!</font><br>"; ob_flush();
                $skipped_file_n ++;
            } else
            {
                echo "<font color=green>Uploading file $localfile_path (file #$uploaded_file_n)..." . date("H:i:s") . "</font><br>"; ob_flush();
                try
                {
                    $object = $container->create_object($filename);
                    $object->load_from_filename($localfile_path);
                    $uploaded_file_n ++;
                }
                catch (Exception $e)
                {
                    echo "<font color=red>Error! Caught exception: ",  $e->getMessage(), " on uploading file <strong>$localfile_path</strong>!</font>" . date("H:i:s") . "<br>"; ob_flush();
                    $errors_count ++;
                }
            }
    
        //  if ($uploaded_file_n >= 10)
        //      break;
        }
        echo "Done! $uploaded_file_n files uploaded. Disconnecting :)" . date("H:i:s") . "<br>"; ob_flush();
        echo "Skipped files: $skipped_file_n<br>"; ob_flush();
        if ($errors_count > 0)
            echo "<font color=red>Erorrs: $errors_count</font><br>"; ob_flush();
    }
    
    function UploadChangedImagesToRackFileCDN($b_force_upload = false)
    {
        $exclude = array
        (
          '.',
          '..',
          '*.html',
          '*.htm',
          '*.php',
          '*.csv',
          '*.log',
          '*.txt',
          '*.cfg',
          //'*sub/forum/files/*',
        );
        $files_array_images = get_dirlist("/var/www/html/vladonai.com/images/", '*', $exclude, false); 
        $files_array = array_merge(get_dirlist("/var/www/html/vladonai.com/js/", '*', $exclude, false), $files_array_images);
    
        UploadMissingFilesToRackFileCDN($files_array, $b_force_upload);
    } 
    
    
    function get_dirlist($path, $match = '*', $exclude = array( '.', '..' ), $b_short_path = true)
    {
        $result = array();
    
        if (($handle = opendir($path)))
        {
            while (false !== ($fname = readdir($handle)))
            {
                $skip = false;
    
                if (!empty($exclude))
                {
                    if (!is_array($exclude))
                    {
                        $skip = fnmatch($exclude, $fname) || fnmatch($exclude, $path . $fname);
                    } else
                    {
                        foreach ($exclude as $ex)
                        {
                            if (fnmatch($ex, $fname) || fnmatch($ex, $path . $fname))
                                $skip = true;
                        }
                    }
                }
    
                if (!$skip && (empty($match) || fnmatch($match, $fname)))
                {
                    $file_full_path_and_name = $path . $fname;
                    //echo "$file_full_path_and_name<br>";
                    $b_dir = is_dir($file_full_path_and_name);
                    $b_link = is_link($file_full_path_and_name);
                    $file_size = ($b_dir || $b_link) ? 0 : filesize($file_full_path_and_name);
                    $file_mod_time = ($b_dir || $b_link) ? 0 : filemtime($file_full_path_and_name);
    
                    $new_result_element = array();
                    if ($b_short_path)
                        $file_name = str_replace("/var/www/html/vladonai.com/", "", $file_full_path_and_name);//'[' . str_replace("/var/www/html/vladonai.com/", "", $file_full_path_and_name) . ']';
                    else
                        $file_name = $file_full_path_and_name;
                    $result[$file_name] = array();
                    $result[$file_name]['size'] = $file_size;
                    $result[$file_name]['modtime'] = $file_mod_time;
    
                    if ($b_dir && !$b_link)
                    {
                        //recursively enumerate files in sub-directories
                        $result = array_merge(get_dirlist($file_full_path_and_name . "/", $match, $exclude, $b_short_path), $result);
                    }
                }
            }
    
            closedir($handle);
        }
    
        return $result;
    }