/******************************************************************************************************** The Truveo Video Search Flash API version 3. Copyright (c) 2007, Truveo LLC. All rights reserved. ********************************************************************************************************/ import mx.events.EventDispatcher; import mx.utils.Delegate; import mx.xpath.XPathAPI; ///////////////////////////////////////////////////////////////////////////////////////// // The TruveoVideoSearch class is the top-level class for the Truveo Video Search Flash API. ///////////////////////////////////////////////////////////////////////////////////////// class TruveoVideoSearch { ///// Member variables with get and/or set privileges // Request attributes private var _appID:String; // application ID private var _results:Number = 10; // number of results to be returned private var _tagResults:Number = 10; // number of related tags to be returned private var _channelResults:Number = 10; // number of related channels to be returned private var _categoryResults:Number = 10; // number of related categories to be returned private var _userResults:Number = 10; // number of related users to be returned private var _showRelatedItems:Number = 0; // flag that indicates if related tags, channels, categories and users should be returned private var _showAdult:Number = 0; // flag that indicates if adult content should be included in result set private var _start:Number = 0; // starting position of the first result // Response attributes private var _method:String; // string containing the name of the API method private var _query:String; // string containing the query that was submitted private var _querySuggestion:String; // string containing a suggested query (if available) private var _videoSet:Object = null; private var _tagSet:Object = null; private var _categorySet:Object = null; private var _channelSet:Object = null; private var _userSet:Object = null; private var _Result:Object = null; ///// Private member variables private var _xmlDoc:XML; // XML document representing the response // Event objects private var _onUpdateEvent:Object = new Object(); // represents "onupdate" event private var _onErrorEvent:Object = new Object(); // represents "onerror" event private var _onLoadEvent:Object = new Object(); // represents "onload" event // Error messages private var _errorMessages:Object = {code_502: "Invalid Flash method call: The wrong number of arguments was provided to this method.", code_503: "Method not available: You must be logged in to use this method.", code_400: "Bad API request or API Service unavailable. Check that the parameters to the request are correctly specified."}; // Constructor for TruveoVideoSearch object. // Parameters: // appID (required): application ID against which all queries will be executed public function TruveoVideoSearch(appID:String) { _appID = appID; // initialize event dispatcher mx.events.EventDispatcher.initialize(this); // initialize event objects _onUpdateEvent.target=this; _onUpdateEvent.type="onupdate"; _onErrorEvent.target=this; _onErrorEvent.type="onerror"; _onLoadEvent.target=this; _onLoadEvent.type="onload"; } /************************************************************************************************** PUBLIC functions that implement APIv3 ***************************************************************************************************/ // Function initialize() // Nothing here yet: needed for user-methods // Events: // onload: This event will be dispatched once the initialization of this object has completed. // Return value: (none) public function initialize():Void { // Throw 'onload' event immediately // Set reloadStateFlag to false for now; this is only true if this object was initialized following a return from the // Truveo account login page. _onLoadEvent.reloadStateFlag = false; dispatchEvent(_onLoadEvent); } // Implements API method: truveo.videos.getVideos // Parameters: // query (optional; defaults to ""): the query to execute. This should follow the format specified in http://developer.truveo.com/SearchQueryOverview.php // start (optional; defaults to 0): the starting position of the first result // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. public function getVideos(query:String, start:Number):Boolean { if (query == null) query=""; // default to empty query if (start == null) start=0; // default to start position of 0 submitRESTQuery({method: "truveo.videos.getVideos", query: query, results: _results, start: start, showRelatedItems: _showRelatedItems, tagResults: _tagResults, channelResults: _channelResults, categoryResults: _categoryResults, userResults: _userResults, showAdult: _showAdult}); return(true); } // Implements API method: truveo.videos.getRelatedTags // Parameters: // query (optional; defaults to ""): the query to execute. This should follow the format specified in http://developer.truveo.com/SearchQueryOverview.php // start (optional; defaults to 0): the starting position of the first result // results (optional; defaults to 10): the number of results the search engine should return; if set, overrides tagResults property // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. public function getRelatedTags(query:String, start:Number, results:Number):Boolean { if (query == null) query=""; // default to empty query if (start == null) start=0; // default to start position of 0 if (results == null) results=_tagResults; // default # of results to value of tagResults property submitRESTQuery({method: "truveo.videos.getRelatedTags", query: query, results: results, start: start}); return(true); } // Implements API method: truveo.videos.getRelatedChannels // Parameters: // query (optional; defaults to ""): the query to execute. This should follow the format specified in http://developer.truveo.com/SearchQueryOverview.php // start (optional; defaults to 0): the starting position of the first result // results (optional; defaults to 10): the number of results the search engine should return; if set, overrides channelResults property // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. public function getRelatedChannels(query:String, start:Number, results:Number):Boolean { if (query == null) query=""; // default to empty query if (start == null) start=0; // default to start position of 0 if (results == null) results=_channelResults; // default # of results to value of channelResults property submitRESTQuery({method: "truveo.videos.getRelatedChannels", query: query, results: results, start: start}); return(true); } // Implements API method: truveo.videos.getRelatedCategories // Parameters: // query (optional; defaults to ""): the query to execute. This should follow the format specified in http://developer.truveo.com/SearchQueryOverview.php // start (optional; defaults to 0): the starting position of the first result // results (optional; defaults to 10): the number of results the search engine should return; if set, overrides categoryResults property // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. public function getRelatedCategories(query:String, start:Number, results:Number):Boolean { if (query == null) query=""; // default to empty query if (start == null) start=0; // default to start position of 0 if (results == null) results=_categoryResults; // default # of results to value of categoryResults property submitRESTQuery({method: "truveo.videos.getRelatedCategories", query: query, results: results, start: start}); return(true); } // Implements API method: truveo.videos.getRelatedUsers // Parameters: // query (optional; defaults to ""): the query to execute. This should follow the format specified in http://developer.truveo.com/SearchQueryOverview.php // start (optional; defaults to 0): the starting position of the first result // results (optional; defaults to 10): the number of results the search engine should return; if set, overrides userResults property // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. public function getRelatedUsers(query:String, start:Number, results:Number):Boolean { if (query == null) query=""; // default to empty query if (start == null) start=0; // default to start position of 0 if (results == null) results=_userResults; // default # of results to value of userResults property submitRESTQuery({method: "truveo.videos.getRelatedUsers", query: query, results: results, start: start}); return(true); } // Implements API method: truveo.videos.submitRating // Parameters: // id (required): the unique id value for an available video in the search engine // rating (required): the rating to be assigned to the given video. Must be number between 0 and 5. // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. 'false' if this function is called with the incorrect number // of arguments. public function submitRating(id:Number, rating:Number):Boolean { if (arguments.length < 2) { _onErrorEvent.errorCode = 502; _onErrorEvent.errorMessage = _errorMessages["code_502"]; dispatchEvent(_onErrorEvent); return(false); } submitRESTQuery({method: "truveo.videos.submitRating", id: id, rating: rating}); return(true); } // Implements convenience method: hasNextPage // Parameters: (none) // Events: (none) // Return value: // 'true' if another page of video search results is available; needs to be called after a call to getVideos() public function hasNextPage():Boolean { if (_videoSet) { return ((parseInt(_videoSet["firstResultPosition"]) + parseInt(_videoSet["totalResultsReturned"])) < parseInt(_videoSet["totalResultsAvailable"])); } return false; } // Implements convenience method: hasPreviousPage // Parameters: (none) // Events: (none) // Return value: // 'true' if a previous page of video search results is available; needs to be called after a call to getVideos() public function hasPreviousPage():Boolean { if (_videoSet) { return (parseInt(_videoSet["firstResultPosition"]) > 0); } return false; } // Implements convenience method: nextPage // Parameters: (none) // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. 'false' if there is no VideoSet available. // Retrieves the VideoSet containing the next page of video search results. public function nextPage() { if (_videoSet) { var newStartPosition = parseInt(_videoSet["firstResultPosition"]) + parseInt(_videoSet["totalResultsReturned"]); getVideos(_query, newStartPosition); return(true); } return(false); } // Implements convenience method: previousPage // Parameters: (none) // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. 'false' if there is no VideoSet available. // Retrieves the VideoSet containing the previous page of video search results. public function previousPage() { if (_videoSet) { var newStartPosition = parseInt(_videoSet["firstResultPosition"]) - _results; getVideos(_query, newStartPosition); return(true); } return(false); } // Implements convenience method: goToPage // Parameters: // pageNum (required): The page number of the video results to return. // Events: // onupdate: This event will be dispatched when the XML results have been received, the XML has been successfully parsed, and the VideoSet // object has been populated. // onerror: This event will be dispatched when the XML results include an Error. // Return value: // 'true' if the XML API request was sent successfully. 'false' if there is no VideoSet available. // Retrieves the page of the VideoSet specified by the pageNum. public function goToPage(pageNum:Number) { if (_videoSet) { var newStartPosition = (pageNum-1) * _results; newStartPosition = (newStartPosition < 0 ? 0 : newStartPosition); getVideos(_query, newStartPosition); return(true); } return(false); } /************************************************************************************************** PUBLIC attributes available in APIv3 ***************************************************************************************************/ // VideoSet (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=VideoSet. // It may have 0 length. function get VideoSet():Object { return _videoSet; } // TagSet (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=TagSet. // It may have 0 length. It may be null. function get TagSet():Object { return _tagSet; } // CategorySet (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=CategorySet. // It may have 0 length. It may be null. function get CategorySet():Object { return _categorySet; } // ChannelSet (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=ChannelSet. // It may have 0 length. It may be null. function get ChannelSet():Object { return _channelSet; } // UserSet (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=UserSet. // It may have 0 length. It may be null. function get UserSet():Object { return _userSet; } // Result (read-only) // Type: Object // This Object is defined here: http://developer.truveo.com/AJAXAPIDataObject.php?name=Result. // It may be null. function get Result():Object { return _Result; } // results (read/write) // Type: Number // The number of results that the XML API will attempt to return in response to the query. // Valid values are integers in [1, 50]. function get results():Number { return _results; } function set results(new_val:Number):Void { _results = new_val; } // start (read/write) // Type: Number // The starting position of the first result that the XML API will attempt to return in response to the query. // Valid value is any integer >= 0. function get start():Number { return _start; } function set start(new_val:Number):Void { _start = new_val; } // tagResults (read/write) // Type: Number // The number of related tags that the XML API will attempt to return in response to the query. Only relevant // if 'showRelatedItems' is set to 1. // Valid value is an integer in [1, 50]. function get tagResults():Number { return _tagResults; } function set tagResults(new_val:Number):Void { _tagResults = new_val; } // channelResults (read/write) // Type: Number // The number of related channels that the XML API will attempt to return in response to the query. Only relevant // if 'showRelatedItems' is set to 1. // Valid value is an integer in [1, 50]. function get channelResults():Number { return _channelResults; } function set channelResults(new_val:Number):Void { _channelResults = new_val; } // categoryResults (read/write) // Type: Number // The number of related categories that the XML API will attempt to return in response to the query. Only relevant // if 'showRelatedItems' is set to 1. // Valid value is an integer in [1, 50]. function get categoryResults():Number { return _categoryResults; } function set categoryResults(new_val:Number):Void { _categoryResults = new_val; } // userResults (read/write) // Type: Number // The number of related users that the XML API will attempt to return in response to the query. Only relevant // if 'showRelatedItems' is set to 1. // Valid value is an integer in [1, 50]. function get userResults():Number { return _userResults; } function set userResults(new_val:Number):Void { _userResults = new_val; } // showRelatedItems(read/write) // Type: Number // Flag that indicates if related tags, channels, categories and users should be included in the result set. // Valid value is one of {0, 1}. function get showRelatedItems():Number { return _showRelatedItems; } function set showRelatedItems(new_val:Number):Void { _showRelatedItems = new_val; } // showAdult (read/write) // Type: Number // Flag that indicates if adult content should be included in the result set. // Valid value is one of {0, 1}. function get showAdult():Number { return _showAdult; } function set showAdult(new_val:Number):Void { _showAdult = new_val; } // method (read-only) // Type: String // A string containing the name of the API method used to retrieve the response. function get method():String { return _method; } // query (read-only) // Type: String // A string containing the original submitted query associated with this response. function get query():String { return _query; } // querySuggestion (read-only) // Type: String // A string containing a suggested query, if available, for the original submitted query associated with this response. // May be undefined. function get querySuggestion():String { return _querySuggestion; } /************************************************************************************************** PRIVATE functions ***************************************************************************************************/ // Function processQueryResults() will be called once the XML API has returned and the XML document has been loaded. // This function parses the resulting XML and populates the _videoSet, _tagSet, _categorySet, _channelSet and _userSet // objects. See comments for parseXMLSet() for details on how these *Set objects are structured. // Throws the "onupdate" event after the XML has been received and successfully parsed. In the response contains // an Error node, the "onerror" event will be thrown. private function processQueryResults(bSuccess:Boolean) { if (bSuccess) { // XML was sucessfully loaded _videoSet = new Object(); var rootNode:XMLNode = _xmlDoc.firstChild; // // Get attributes of the Response element: method, query, querySuggestion parseResponseAttributes(rootNode); // Convert XML for VideoSet to an object representation _videoSet = parseXMLSet(rootNode, "Video"); // Convert XML for TagSet to an object representation _tagSet = parseXMLSet(rootNode, "Tag"); // Convert XML for CategorySet to an object representation _categorySet = parseXMLSet(rootNode, "Category"); // Convert XML for ChannelSet to an object representation _channelSet = parseXMLSet(rootNode, "Channel"); // Convert XML for UserSet to an object representation _userSet = parseXMLSet(rootNode, "User"); // Convert XML for Result to an object representation _Result = parseResult(rootNode); } else { // This means either the XML API service couldn't be contacted, or the API returned an error. When the // API returns an error, the HTTP response code will be one of: Bad request 400, Forbidden 403 or Service // Unavailable 503. All of these are interpreted as 'bSuccess==false' in Flash. trace ("TruveoVideoSearch.processQueryResults(): Error loading XML or Error in API request."); //parseXMLError(_xmlDoc.firstChild); // get the error code + message that the API returned // Note: the Flash XML class throws away the response body if the HTTP response is a non-200 // status code. As a result, the API will throw a generic error for all non-200 responses from the API. _onErrorEvent.errorCode = 400; _onErrorEvent.errorMessage = _errorMessages["code_400"]; dispatchEvent(_onErrorEvent); // throw the "onerror" event return; } _onUpdateEvent.methodName = _method; dispatchEvent(_onUpdateEvent); } // Function parseResult parses the XML response from methods that return a element (submitRating, addFavorite). // The returned object is an associative array. private function parseResult(rootNode:XMLNode) { var resultObj = new Object(); // Convert XML for Result to an object representation var resultElt:XMLNode = XPathAPI.selectSingleNode(rootNode, "/Response/Result"); for (var curNode=resultElt.firstChild; curNode != null; curNode=curNode.nextSibling) { resultObj[curNode.nodeName] = curNode.firstChild.nodeValue; } return resultObj; } // Function parseXMLSet() parses the XML for a given Set node and returns an object representation. // The Set node is determined by the given 'setType' string, which must be one of: {Video, Tag, Category, Channel, User}. // Set nodes (i.e., , , , , or ) are structured in // the following way: they may have any number of child nodes at one level deep that correspond to attributes of the // Set. These attributes will be stored as properties of the returned object (that can be accessed as if the object is // an associative array). These are followed by the elements for that Set, which are all one level deep children of the root set node. // The names of these element tags should match the given 'setType' string: e.g., for a VideoSet these elements are // called