DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Jonnie has posted 12 posts at DZone. View Full User Profile

Full Del.icio.us API Service In AS3

10.18.2008
| 4481 views |
  • submit to reddit
        Wanna make some calls to del.icio.us

Here is a great example.

/** *******************************************************************
 * MySnippets
 * Free for use
 *
 * @author  Jonnie Spratley
 * @contact jonniespratley@gmail.com
 ******************************************************************* */
package com.jonniespratley.itsdeliciousair.service
{
	import com.adobe.net.URI;
	import com.adobe.utils.DateUtil;
	import com.arc90.rpc.events.FaultEvent;
	import com.arc90.rpc.events.ResultEvent;
	import com.arc90.rpc.rest.RESTService;
	import com.arc90.rpc.rest.RESTServiceMethod;
	import com.jonniespratley.itsdeliciousair.managers.DatabaseManager;
	import com.jonniespratley.itsdeliciousair.model.ModelLocator;
	import com.jonniespratley.itsdeliciousair.vo.BundleVO;
	import com.jonniespratley.itsdeliciousair.vo.PostVO;
	import com.jonniespratley.itsdeliciousair.vo.TagVO;
	import com.jonniespratley.itsdeliciousair.vo.UserVO;
	
	import flash.xml.XMLDocument;
	import flash.xml.XMLNode;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	import mx.managers.CursorManager;

	public class DeliciousAPIService implements IDeliciousService
	{
		
		//Del.icio.us Base API URL
		private var endpoint:String = "https://api.del.icio.us/v1/";
		
		//Del.icio.us RSS URL
		private var feedURL:String = "http://feeds.delicious.com/v2/rss/";
		
		//Del.icio.us Home URL
		private var baseURL:String = "http://del.icio.us/";
		
		//Our Database Connection
		private var database:DatabaseManager = new DatabaseManager();
		
		//Our REST Service variable
		private var service:RESTService;
		
		//Our model for updating the data
		[Bindable] private var model:ModelLocator = ModelLocator.getInstance();
		
		public function DeliciousAPIService()
		{
			service = new RESTService();
			service.addEventListener( FaultEvent.FAULT, onFault );	
		}
		
		//Helper for sending calls
		/**
		 * Sends calls to Del.icio.us's api,  
		 * @param user the current user
		 * @param uri the method on the api
		 * @param resultHandler the result handler
		 * 
		 */		
		private function sendQuery( user:UserVO, uri:URI, resultHandler:Function ):void
		{
			CursorManager.setBusyCursor();
			model.readyForCall = false
						
			
			//Set the credentials
			service.setCredentials( user.username, user.password );
		
			service.contentType = RESTService.CONTENT_TYPE_XML;
		
			service.requestTimeout = 1000;
		
			//Set the call url
			service.url = uri.toString();
			
			//Send the call
			service.send();
			
			//Add a result listener
			service.addEventListener( ResultEvent.RESULT, resultHandler );
		
			//trace the url
			trace( "Service URL: " + service.url );
		}
		

		public function checkAccount( aUser:UserVO ):void
		{
			CursorManager.setBusyCursor();
			
			//Set the credentials
			service.setCredentials( aUser.username, aUser.password );
			
			//Set the URL
			service.url = endpoint + "posts/update";
			
			//Set the Method
			service.method = RESTServiceMethod.GET;
			
			//Send It
			service.send();
			
			//Add event Listener
			service.addEventListener( ResultEvent.RESULT, onResult_checkAccount );
			
			//Set the User in the Model to the username and passowrd
			model.currentUser = new UserVO(  aUser.username, aUser.password ); 			
		}
		
		public function addPost(aUser:UserVO, aPost:PostVO):void
		{
			var queryURL:URI = new URI( endpoint + "posts/add" );
				queryURL.setQueryValue( "url", aPost.url.toString() );
				
			var today:Date = new Date();
				
			//Check if there is any data in the fields
			if ( aPost.title != "" )
			{
				queryURL.setQueryValue( "description", aPost.title );							
			}
			
			if ( aPost.description != "" )
			{
				queryURL.setQueryValue( "extended", aPost.description );		
			}
			
			if ( aPost.tags != null )
			{
				queryURL.setQueryValue( "tags", aPost.tags.toArray().join( " " ) );
			}			
			
			//queryURL.setQueryValue( "dt", DateUtil.toW3CDTF( today ) );
			
			if ( aPost.shared == "yes" )
			{
			//	queryURL.setQueryValue( "shared", aPost.shared ? "yes" : "no" );		
			}
				//queryURL.setQueryValue( "replace", aPost.replace ? "yes" : "no" );
			
			//Send out
			sendQuery( aUser, queryURL, onResult_addPost );								
		}
		
		public function removePost(aUser:UserVO, byURL:URI):void
		{
			var queryURL:URI = new URI( endpoint + "posts/delete" );
				queryURL.setQueryValue( "url", byURL.toString() );
				
			sendQuery( aUser, queryURL, onResult_removePost );
		}
		
		public function searchPosts(aUser:UserVO, aTag:String=null, aDate:Date=null, aURL:URI=null, aHash:String=null, aMeta:String="yes"):void
		{
		}
		
		public function getPostDates(aUser:UserVO, aTag:String=null):void
		{
		}
		
		public function getRecentPosts(aUser:UserVO, aTag:String=null, aCount:String = "35"):void
		{
			var queryURL:URI = new URI( endpoint + "posts/recent" );
				
			if ( aCount != null )
			{
				queryURL.setQueryValue( "count", aCount );				
			}
			if ( aTag != null )
			{
				queryURL.setQueryValue( "tag", aTag );				
			}
			
			//Send out
			sendQuery( aUser, queryURL, onResult_getPosts );
		}
		
		public function getAllPosts(aUser:UserVO, aTag:String=null, aStart:String=null, aResults:String=null, aFromDT:Date=null, aToDT:Date=null, aMeta:String="yes"):void
		{
			var queryURL:URI = new URI( endpoint + "posts/all" );
			
			if ( aTag != null )
			{
				queryURL.setQueryValue( "tag", aTag );				
			}
			if ( aStart != null )
			{
				queryURL.setQueryValue( "start", aStart );				
			}
			if ( aResults != null )
			{
				queryURL.setQueryValue( "results", aResults );				
			}
			if ( aFromDT != null )
			{
				queryURL.setQueryValue( "fromdt", DateUtil.toW3CDTF( aFromDT ) );				
			}
			if ( aToDT != null )
			{
				queryURL.setQueryValue( "todt", DateUtil.toW3CDTF( aToDT ) );				
			}
			if ( aMeta != null )
			{
				queryURL.setQueryValue( "meta", aMeta );				
			}
			
			//Send out
			sendQuery( aUser, queryURL, onResult_getPosts );
		}
		
		public function getAllPostHashes(aUser:UserVO):void
		{
		}
		
		public function getTags(aUser:UserVO):void
		{
			var queryURL:URI = new URI( endpoint + "tags/get" );
			
			sendQuery( aUser, queryURL, onResult_getTags );
		}
		
		public function renameTag(aUser:UserVO, aOldName:String, aNewName:String):void
		{
			var queryURL:URI = new URI( endpoint + "tags/rename" );
				queryURL.setQueryValue( "old", aOldName );
				queryURL.setQueryValue( "new", aNewName );
			
			//Send out
			sendQuery( aUser, queryURL, onResult_renameTag );	
		}
		
		public function removeTag(aUser:UserVO, aWhatTag:String):void
		{
			var queryURL:URI = new URI( endpoint + "tags/delete" );
				queryURL.setQueryValue( "tag", aWhatTag );
			
			//Send out
			sendQuery( aUser, queryURL, onResult_removeTag );
		}
		
		public function getBundles(aUser:UserVO, aBundle:String=null):void
		{
			var queryURL:URI = new URI( endpoint + "tags/bundles/all" );
			
			sendQuery( aUser, queryURL, onResult_getBundles );
		}
		
		public function setBundle(aUser:UserVO, aBundle:BundleVO):void
		{
			var queryURL:URI = new URI( endpoint + "tags/bundles/set" );
			
				queryURL.setQueryValue( "bundle", aBundle.name );
				queryURL.setQueryValue( "tags", aBundle.tags.toArray().join( " " ) );
			
			sendQuery( aUser, queryURL, onResult_setBundle );  
		}
		
		public function removeBundle(aUser:UserVO, aBundle:String):void
		{
			var queryURL:URI = new URI( endpoint + "tags/bundles/" );
				queryURL.setQueryValue( "delete", aBundle );
			
			sendQuery( aUser, queryURL, onResult_removeBundle );	
		}
				
		
		/* 
		#############################################################################
		#																			#
		#				Result Handles for all calls								#
		#																			#
		#############################################################################
		*/
		
		/**
		 * Changes the workflowState to welcome screen.
		 *  
		 * @param d_result
		 * 
		 */		
		private function onResult_checkAccount( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			
			//Check if we got a ok response
			if (  d_result.statusCode == 200 )
			{
				//Add the data to the user in the model
				model.currentUser.lastupdated = DateUtil.parseW3CDTF( d_result.result.@time );
				model.currentUser.inboxcount = d_result.result.@inboxnew;
				
				//Set the isLoggedIn to true
				model.isLoggedIn = true;
				
				//Change the workflow state
				model.workflowState = ModelLocator.DASHBOARD_SCREEN;
				
				//And save the user's info to the database for offline usage			 	
			 	database.saveUser( model.currentUser );
				
			
			} else {
				//Alert the user
				Alert.show( "There was a Problem" );
			}
			trace( "\nStatus Code: " + d_result.statusCode + "\nStatus Message: " + d_result.statusMessage );
		}
		
		/**
		 * Here is the xml result:
		 * 
		 * <?xml version="1.0" encoding="UTF-8"?>
		 * <tags>
		 * 		<tag count="1" tag="30boxes"/>
		 * 		<tag count="1" tag="JavaScript"/>
		 * 		<tag count="4" tag="Software"/>
		 * 		<tag count="3" tag="Web_2.0"/>
		 * </tags> 
		 * 
		 * Takes the result as xml, parses it and then 
		 * adds the data accordingly to the tag object
		 * then adds the data to the model.
		 *  
		 * @param d_result
		 * 
		 */		
		private function onResult_getTags( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
			
			//Remove the busy cursor manually
			CursorManager.removeBusyCursor();
									
			//Create a new xml object
			var resultNode:XML;			
			
			//Create a array to add the xml to
			var result:Array = new Array();					
			
				//Check if the result status code, if we get a 200 then parse the xml, else show error
				if ( d_result.statusCode == 200 ) 
				{									
					//Make the result of the request as xml
					var tagXML:XML = new XML( d_result.result );
			
					//Then parse the xml, for each node in xml 
					for each ( resultNode in tagXML.children() )
					{			
						//Create a new Tag from the result			
							//the tag_count is set to the result.@count attribute							
								//the tag_name is set to the result.@tag attribute 
						var tag:TagVO = new TagVO( resultNode.@tag, 
												   resultNode.@count );						
							
						//Add the tag to our array
						result.push( tag );
						
						//Add the array to our model for binding
						model.tagCollection = new ArrayCollection( result );					
					}
				}
				
			//Trace the bs
			trace( "Result Headers: " + d_result.headers +
				   "\nResult Status Message: " + d_result.statusMessage +
				   "\nResult Status Code: " + d_result.statusCode +
				   "\nResult XML: " + d_result.result );
		}
		
		/**
		 * 
		 * @param event
		 * 
		 */		
		private function onResult_removeTag( d_event:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			
			trace( d_event.statusCode );
		}		
		
		
		/**
		 * 
		 * @param event
		 * 
		 */		
		private function onResult_renameTag( d_event:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			
			trace( d_event.statusCode );
		}		
		
		
		/**
		 * Save Post Result Handler
		 * @param event
		 * 
		 */		
		private function onResult_addPost( d_event:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			
			trace( d_event.statusCode );
		}
		
		/**
		 * 
		 * @param event
		 * 
		 */		
		private function onResult_removePost( d_event:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			
			trace( d_event.statusCode );
		}			
		
		/**
		 * Here is the xml result:
		 * 
		 * <posts user="jonniedollas" update="2008-09-13T06:03:26Z" tag="" total="264">
		 * 		<post 
	 	 * 			href="http://airapps.pbwiki.com/" 
	 	 * 			hash="736123a4e2b3250e6919fa7538a810d1" 
	 	 * 			description="airapps wiki" 
	 	 * 			tag="flex ria web2.0" 
	 	 * 			time="2008-09-13T05:59:12Z" 
	 	 * 			extended=""
	 	 * 			shared="no"/>
	 	 * </posts>
		 * 
		 * 
		 * Takes the result as xml, parses it and then 
		 * adds the data accordingly to the DeliciousPost,
		 * then adds the data to the model.
		 * 
		 * 
		 * @param d_result
		 * 
		 */		
		private function onResult_getPosts( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
			
			//Remove the busy cursor manually	
			CursorManager.removeBusyCursor();
			
			//Create a new xml object
			var resultNode:XML;			
			
			//Create a array to add the xml to
			var result:Array = new Array();
			
				//Check if the result status code, if we get a 200 then parse the xml, else show error
				if ( d_result.statusCode == 200 ) 
				{				
					//Make the result of the request as xml
					var postXML:XML = new XML( d_result.result );
					
			
					
					//Then parse the xml, for each node in xml 
					for each ( resultNode in postXML.children() )
					{						
						var post:PostVO = new PostVO( new URI( resultNode.@href ),
													  resultNode.@description, 
													  resultNode.@extended, 
													  new ArrayCollection( String( resultNode.@tag ).split( " " ) ) ,
													  resultNode.@shared,					
													  DateUtil.parseW3CDTF( resultNode.@time ) );
					
							//Add the post to our array
							result.push( post );						
							
						//And now add the result array to our model for binding	
						model.postCollection = new ArrayCollection( result );					
					}											
				}			
				trace( model.deliciousMessage );
			//Trace the bs				
			trace( "\nResult Headers: " + d_result.headers.toString() +
			"\nResult Status Message: " + d_result.statusMessage +
			"\nResult Status Code: " + d_result.statusCode +
			"\nResult XML: " + d_result.result as XML );		
		}		
		
			
		/**
		 * Handles the result.
		 *  
		 * @param event
		 * 
		 */		
		private function onResult_setBundle( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			trace( d_result.result );			
		}
		
		/**
		 * Handles the reuslt for now
		 *  
		 * @param event
		 * 
		 */		
		private function onResult_getBundles( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
					
			CursorManager.removeBusyCursor();
			trace( d_result.result );
		}	
		
		/**
		 * Handles the reuslt for now
		 *  
		 * @param event
		 * 
		 */		
		private function onResult_removeBundle( d_result:ResultEvent ):void
		{
			model.readyForCall = true;
			
			CursorManager.removeBusyCursor();
			trace( d_result.result );
		}
		
		 /**
		  * Takes all the posts recieved from del.icio.us
		  * and imports them into our database.
		  *  
		  * @param d_result the xml
		  * 
		  */		 
		 private function onResult_importAllPosts( d_result:ResultEvent ):void
		 {
		 	model.readyForCall = true;
		 	
		 	//Remove Cursor
		 	CursorManager.removeBusyCursor();		
		 	
		 	//Create a xml document
		 	var xml:XMLDocument = new XMLDocument();
		 		//gotta ignore the whitespace
		 		xml.ignoreWhite = true;
		 		//Parse that xml
		 		xml.parseXML( d_result.result as XML );
		 		
		 		//Loop it
		 		for each ( var item:XMLNode in xml.firstChild.childNodes )
		 		{
		 			//Import it
		 			database.importPostXML( item, model.currentUser );
		 			
		 			trace( "\n\nXML Item: " + item );
				}
				trace( "\nImporting Data" );		
		 }
		
		/**
		 *  Handles the faults
		 * 
		 * @param event
		 * 
		 */				
		private function onFault( event:FaultEvent ):void
		{
			model.readyForCall = true;
			
			//Add Code
			 CursorManager.removeBusyCursor();
			
			//If Statement
			if ( event.fault.faultCode == "401" )
			{
				//Alert the User
				Alert.show( event.fault.faultString, event.fault.faultCode );
				//Set logged in to false
				model.isLoggedIn = false;
				//Clear user
				model.currentUser = null;				
			}
			//trace
			trace( "\nFault Detail: " + event.fault.faultDetail + 
					"\nFault Code: " + event.fault.faultCode +
					"\nFault String: " + event.fault.faultString );
		}	
		
	}
}

You should be able to figure how to call this from a view. here is a little snip from one.

<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" horizontalAlign="center" verticalAlign="middle">
	<mx:Script>
		<![CDATA[
			import mx.rpc.events.ResultEvent;
			import mx.rpc.http.HTTPService;	
			import com.jonniespratley.advguidetoflex.webapis.DeliciousService;
			
			private var service:DeliciousService = new DeliciousService();
			
			private function doLogin():void
			{
				service.checkAccount( txt_username.text, txt_password.text );				
			}
		
		]]>
	</mx:Script>
	<mx:HBox verticalAlign="middle">
		<mx:Image source="assets/logos/delicious_32x32.png"/>
		<mx:Label text="Del.icio.us" fontWeight="bold" fontSize="16"/>
	</mx:HBox>
	
	<!--UserLogin-->
	<mx:Form width="100%">
	
		<!--Del.icio.us Username-->
		<mx:FormItem label="Username:" width="100%" required="true" labelStyleName="formLabel">
			<mx:TextInput id="txt_username"
				width="100%"/>
		</mx:FormItem>
		
		<!--Del.icio.us Password-->
		<mx:FormItem label="Password:" width="100%" required="true" labelStyleName="formLabel">
			<mx:TextInput id="txt_password"
				displayAsPassword="true" 
				width="100%"/>
		</mx:FormItem>
		
		<!--Del.icio.us Login-->
		<mx:FormItem width="100%" horizontalAlign="right" direction="horizontal">			
			<mx:Button id="btn_login"
				label="Login" 
				click="doLogin()"/>						
		</mx:FormItem>			
	</mx:Form>
</mx:VBox>