<!--- Kill extra output. ---> <cfsilent> <!--- Param the FORM variable that will hold our photo urls. Remember, each URL is on its own line (separrated by line returns). ---> <cfparam name="FORM.photo_url" type="string" default="" /> <!--- Trim the form field. ---> <cfset FORM.photo_url = FORM.photo_url.Trim() /> <!--- Check to see if the form has been submitted. For this demo, we will know this if there is a value in the form field. ---> <cfif Len( FORM.photo_url )> <!--- Loop over the URLs. We can treat the text area as if it were a list of URLs that is using the line break, line return as the list delimiter. ---> <cfloop index="strURL" list="#FORM.photo_url#" delimiters="#Chr( 13 )##Chr( 10 )#"> <!--- Now that we have our individual URL, let's grab the photo binary using CFHttp and store it directly into a file on the server. We are going to launch this CFHttp call in a new thread using CFThread. We are not going to wait for this call to finish. ---> <cfthread action="run" name="photo_#GetFileFromPath( strURL )#"> <!--- Let the current thread save itself to the threads struct in the application. While there is a possible race condition here (since other parts of the code will be reading from this struct), for this demo it is not going to be an issue. Also, notice that we are not passing the THREAD scope itself. This is crutial as the THREAD scope is a very special scope. By duplicating it we are turning it into a ColdFusion runtime struct (much better for our purposes). ---> <cfset APPLICATION.Threads[ THREAD.Name ] = Duplicate( THREAD ) /> <!--- Save the photo. ---> <cfhttp url="#strURL#" method="GET" getasbinary="yes" path="#ExpandPath( './data/' )#" file="#GetFileFromPath( strURL )#" /> <!--- Now that the thread has finished running, have this thread remove itself from the application threads struct. ---> <cfset StructDelete( APPLICATION.Threads, THREAD.Name ) /> </cfthread> </cfloop> </cfif> </cfsilent> <cfoutput> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>ColdFusion 8 - CFThread Demo</title> <!--- Include the jQuery scripts. ---> <script type="text/javascript" src="jquery-latest.pack.js"> </script> <script type="text/javascript"> // Load the thread activity via jQuery's // AJAX functionality. This will load the // returned value into the innerHTML. function UpdateThreadActivity(){ $( "##threadactivity" ).load( "./get_threads.cfm", {}, function(){ setTimeout( UpdateThreadActivity, 250 ); } ); } // When the document has loaded, start // updating the thread activity. $( UpdateThreadActivity ); </script> </head> <body> <h2> Flickr.com Photo Download </h2> <!--- Check to see if the form as been submitted. For this demo, we will know this if there is a value in the form field. ---> <cfif NOT Len( FORM.photo_url )> <p> Please enter photo URLs that you would like to download. Each URL should be on a single line of the following text area. </p> <form action="#CGI.script_name#" method="post"> <p> <textarea name="photo_url" cols="70" rows="20" >#FORM.photo_url#</textarea> </p> <p> <input type="submit" value="Download Now" /> </p> </form> <cfelse> <p> Your photos are being downloaded right now: </p> <!--- This part will be updated via jQuery and some nice AJAX requests (see HTML head). ---> <p id="threadactivity"> Gathering thread activity... </p> </cfif> </body> </html> </cfoutput>