How to talk to Flickr using ColdFusion 2006 02 28

We all know about Flickr, or at least we all should and if you don't, it's time to catch up. Flickr is an incredible photo sharing and community tool created by the minds of Ludicorp. Luckily, they decided to share this great tool with us in the form of a robust API.

Many groups have already harnessed this API for langauges such as .NET, PHP and ActionScript. There was no API wrapper linked from Flickr for ColdFusion, so I did some digging and realised it's because it's so easy to utilize the REST method, that an extensive and bulky wrapper was not needed. So I decided to explore this in tandem with the ideas I had for AJAX. I will explain the basics of what I did and provide a remedial version of the custom tag.

Okay, first I'll show you all the code that it takes to retrieve photos from Flickr

<cf_Flickr argList="method|flickr.photos.search,user_id|#NSID#,text|#tag#,per_page|500">

That's it, the attribute argList supports all the arguments provided within the Flickr API documentation. Argument sets are separated by commas and values by pipes. In the example above I am requesting the method photos.search and passing user_id, min_upload_date and photos per page.

Next I compile the argList value into an array of structures for later use.

<cfset params = arrayNew(1) />
<cfset params[1] = structNew() />
<cfset params[1].name = "api_key" />
<cfset params[1].value = "#request.key#" />
<!--- loop over this functions arguments to build remaining request arguments --->
<cfset paramArr = listToArray(argList) />
<cfloop index="a" from="1" to="#arrayLen(paramArr)#">
	<cfset params[arrayLen(params) + 1] = structNew() />
	<cfset params[arrayLen(params)].name = listFirst(paramArr[a], "|") />
	<cfset params[arrayLen(params)].value = listLast(paramArr[a], "|") />
	<cfif listFirst(paramArr[a], "|") IS "method">
		<cfset thisMethod = listLast(paramArr[a], "|") />
	</cfif>
</cfloop> 
<!--- get returned packet --->
<cfset doc="FlickrHTTP(params)" />

The next function FlickrHTTP gets the REST packet.

<cffunction name="FlickrHTTP">
	<cfargument name="params" />
	<cfhttp url="#request.api#" method="POST">
		<cfloop index="x" from="1" to="#arrayLen(params)#">
	  		<cfhttpparam name="#params[x].name#" type="url" value="#params[x].value#" />
	  	</cfloop>
	</cfhttp>
	<cfset XMLString = REReplace(cfhttp.fileContent, "[^[:print:]]", "", "ALL") />
	<cfreturn XMLParse(XMLString) />
</cffunction>

Now that I have the XML packet, I can go ahead and sift through the dataset and manipulate it the way I want. I prefer to deal with data as a query object, so naturally I convert this nested structure. I'll user a simple example:

<cffunction name="FlickrGetPhotosStructure">
	<cfargument name="baseNode" />
	<!--- what are the columns? --->
	<cfset cols = listToArray(structKeyList(baseNode[1].XMLAttributes)) />
	<cfset responseQuery = queryNew(arrayToList(cols)) />
	<!--- build query --->
	<cfset queryAddRow(responseQuery, arrayLen(baseNode)) />
	<cfloop index="n" from="1" to="#arrayLen(baseNode)#">
		<cfloop index="c" from="1" to="#arrayLen(cols)#">
			<cfscript>
				thisStruct = structFindKey(baseNode[n].XMLAttributes, cols[c]);
				querySetCell(responseQuery, cols[c], thisStruct[1].value, n);
			</cfscript>
		</cfloop>
	</cfloop>
	<cfreturn responseQuery />
</cffunction>

The above variable, responseQuery, returns a query that can be used with a cfoutput tag to display certain information. Here is a simple example using this code, you can enter your NSID (not your username) and look through your photos and tag cloud. You can find your NSID within your RSS feed.



Tags for this article

Comments

Joe Nicora 2006 05 09 FYI: all the code for this Flickr API has changed. I decided it was a better idea not to try and convert every result into a flat query object but instead let the developer handle the XML response data model.

Leave a comment



< Back