diff options
Diffstat (limited to 'includes/js/dojox/data/FlickrRestStore.js')
-rw-r--r-- | includes/js/dojox/data/FlickrRestStore.js | 471 |
1 files changed, 0 insertions, 471 deletions
diff --git a/includes/js/dojox/data/FlickrRestStore.js b/includes/js/dojox/data/FlickrRestStore.js deleted file mode 100644 index 466d6df..0000000 --- a/includes/js/dojox/data/FlickrRestStore.js +++ /dev/null @@ -1,471 +0,0 @@ -if(!dojo._hasResource["dojox.data.FlickrRestStore"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. -dojo._hasResource["dojox.data.FlickrRestStore"] = true; -dojo.provide("dojox.data.FlickrRestStore"); - -dojo.require("dojox.data.FlickrStore"); - -dojo.declare("dojox.data.FlickrRestStore", - dojox.data.FlickrStore, { - constructor: function(/*Object*/args){ - // summary: - // Initializer for the FlickrRestStore store. - // description: - // The FlickrRestStore is a Datastore interface to one of the basic services - // of the Flickr service, the public photo feed. This does not provide - // access to all the services of Flickr. - // This store cannot do * and ? filtering as the flickr service - // provides no interface for wildcards. - if(args && args.label){ - if(args.label) { - this.label = args.label; - } - if(args.apikey) { - this._apikey = args.apikey; - } - } - this._cache = []; - this._prevRequests = {}; - this._handlers = {}; - this._prevRequestRanges = []; - this._maxPhotosPerUser = {}; - this._id = dojox.data.FlickrRestStore.prototype._id++; - }, - - // _id: Integer - // A unique identifier for this store. - _id: 0, - - // _requestCount: Integer - // A counter for the number of requests made. This is used to define - // the callback function that Flickr will use. - _requestCount: 0, - - // _flickrRestUrl: String - // The URL to the Flickr REST services. - _flickrRestUrl: "http://www.flickr.com/services/rest/", - - // _apikey: String - // The users API key to be used when accessing Flickr REST services. - _apikey: null, - - // _storeRef: String - // A key used to mark an data store item as belonging to this store. - _storeRef: "_S", - - // _cache: Array - // An Array of all previously downloaded picture info. - _cache: null, - - // _prevRequests: Object - // A HashMap used to record the signature of a request to prevent duplicate - // request being made. - _prevRequests: null, - - // _handlers: Object - // A HashMap used to record the handlers registered for a single remote request. Multiple - // requests may be made for the same information before the first request has finished. - // Each element of this Object is an array of handlers to call back when the request finishes. - // This prevents multiple requests being made for the same information. - _handlers: null, - - // _sortAttributes: Object - // A quick lookup of valid attribute names in a sort query. - _sortAttributes: { - "date-posted": true, - "date-taken": true, - "interestingness": true - }, - - _fetchItems: function(request, fetchHandler, errorHandler){ - // summary: Fetch flickr items that match to a query - // request: - // A request object - // fetchHandler: - // A function to call for fetched items - // errorHandler: - // A function to call on error - var query = {}; - if(!request.query){ - request.query = query = {}; - } else { - dojo.mixin(query, request.query); - } - - var primaryKey = []; - var secondaryKey = []; - - //Generate a unique function to be called back - var callbackFn = "FlickrRestStoreCallback_" + this._id + "_" + (++this._requestCount); - //Build up the content to send the request for. - var content = { - format: "json", - method: "flickr.photos.search", - api_key: this._apikey, - extras: "owner_name,date_upload,date_taken", - jsoncallback: callbackFn - }; - var isRest = false; - if(query.userid){ - isRest = true; - content.user_id = request.query.userid; - primaryKey.push("userid"+request.query.userid); - } - if(query.apikey){ - isRest = true; - content.api_key = request.query.apikey; - secondaryKey.push("api"+request.query.apikey); - } else{ - throw Error("dojox.data.FlickrRestStore: An API key must be specified."); - } - request._curCount = request.count; - if(query.page){ - content.page = request.query.page; - secondaryKey.push("page" + content.page); - }else if(typeof(request.start) != "undefined" && request.start != null) { - if(!request.count){ - request.count = 20; - } - var diff = request.start % request.count; - var start = request.start, count = request.count; - //If the count does not divide cleanly into the start number, - //more work has to be done to figure out the best page to request - if(diff != 0) { - if(start < count / 2) { - //If the first record requested is less than half the amount requested, - //then request from 0 to the count record - count = start + count; - start = 0; - } else { - var divLimit = 20, div = 2; - for(var i = divLimit; i > 0; i--) { - if(start % i == 0 && (start/i) >= count){ - div = i; - break; - } - } - count = start/div; - } - request._realStart = request.start; - request._realCount = request.count; - request._curStart = start; - request._curCount = count; - } else { - request._realStart = request._realCount = null; - request._curStart = request.start; - request._curCount = request.count; - } - - content.page = (start / count) + 1; - secondaryKey.push("page" + content.page); - } - if(request._curCount){ - content.per_page = request._curCount; - secondaryKey.push("count" + request._curCount); - } - - if(query.lang){ - content.lang = request.query.lang; - primaryKey.push("lang" + request.lang); - } - var url = this._flickrRestUrl; - - if(query.setid){ - content.method = "flickr.photosets.getPhotos"; - content.photoset_id = request.query.set; - primaryKey.push("set" + request.query.set); - } - - if(query.tags){ - if(query.tags instanceof Array){ - content.tags = query.tags.join(","); - } else { - content.tags=query.tags; - } - primaryKey.push("tags" + content.tags); - - if(query["tag_mode"] && (query.tag_mode.toLowerCase() == "any" - || query.tag_mode.toLowerCase() == "all")){ - content.tag_mode = query.tag_mode; - } - } - if(query.text){ - content.text=query.text; - primaryKey.push("text:"+query.text); - } - - //The store only supports a single sort attribute, even though the - //Read API technically allows multiple sort attributes - if(query.sort && query.sort.length > 0){ - //The default sort attribute is 'date-posted' - if(!query.sort[0].attribute){ - query.sort[0].attribute = "date-posted"; - } - - //If the sort attribute is valid, check if it is ascending or - //descending. - if(this._sortAttributes[query.sort[0].attribute]) { - if(query.sort[0].descending){ - content.sort = query.sort[0].attribute + "-desc"; - } else { - content.sort = query.sort[0].attribute + "-asc"; - } - } - } else { - //The default sort in the Dojo Data API is ascending. - content.sort = "date-posted-asc"; - } - primaryKey.push("sort:"+content.sort); - - //Generate a unique key for this request, so the store can - //detect duplicate requests. - primaryKey = primaryKey.join("."); - secondaryKey = secondaryKey.length > 0 ? "." + secondaryKey.join(".") : ""; - var requestKey = primaryKey + secondaryKey; - - //Make a copy of the request, in case the source object is modified - //before the request completes - request = { - query: query, - count: request._curCount, - start: request._curStart, - _realCount: request._realCount, - _realStart: request._realStart, - onBegin: request.onBegin, - onComplete: request.onComplete, - onItem: request.onItem - }; - - var thisHandler = { - request: request, - fetchHandler: fetchHandler, - errorHandler: errorHandler - }; - - //If the request has already been made, but not yet completed, - //then add the callback handler to the list of handlers - //for this request, and finish. - if(this._handlers[requestKey]){ - this._handlers[requestKey].push(thisHandler); - return; - } - - this._handlers[requestKey] = [thisHandler]; - - //Linking this up to Flickr is a PAIN! - var self = this; - var handle = null; - var getArgs = { - url: this._flickrRestUrl, - preventCache: true, - content: content - }; - - var doHandle = function(processedData, data, handler){ - var onBegin = handler.request.onBegin; - handler.request.onBegin = null; - var maxPhotos; - var req = handler.request; - - if(typeof(req._realStart) != undefined && req._realStart != null) { - req.start = req._realStart; - req.count = req._realCount; - req._realStart = req._realCount = null; - } - - //If the request contains an onBegin method, the total number - //of photos must be calculated. - if(onBegin){ - if(data && typeof(data.photos.perpage) != "undefined" && typeof(data.photos.pages) != "undefined"){ - if(data.photos.perpage * data.photos.pages <= handler.request.start + handler.request.count){ - //If the final page of results has been received, it is possible to - //know exactly how many photos there are - maxPhotos = handler.request.start + data.photos.photo.length; - }else{ - //If the final page of results has not yet been received, - //it is not possible to tell exactly how many photos exist, so - //return the number of pages multiplied by the number of photos per page. - maxPhotos = data.photos.perpage * data.photos.pages; - } - self._maxPhotosPerUser[primaryKey] = maxPhotos; - onBegin(maxPhotos, handler.request); - } else if(self._maxPhotosPerUser[primaryKey]) { - onBegin(self._maxPhotosPerUser[primaryKey], handler.request); - } - } - //Call whatever functions the caller has defined on the request object, except for onBegin - handler.fetchHandler(processedData, handler.request); - if(onBegin){ - //Replace the onBegin function, if it existed. - handler.request.onBegin = onBegin; - } - }; - - //Define a callback for the script that iterates through a list of - //handlers for this piece of data. Multiple requests can come into - //the store for the same data. - var myHandler = function(data){ - //The handler should not be called more than once, so disconnect it. - //if(handle !== null){ dojo.disconnect(handle); } - if(data.stat != "ok"){ - errorHandler(null, request); - }else{ //Process the items... - var handlers = self._handlers[requestKey]; - if(!handlers){ - console.log("FlickrRestStore: no handlers for data", data); - return; - } - - self._handlers[requestKey] = null; - self._prevRequests[requestKey] = data; - - //Process the data once. - var processedData = self._processFlickrData(data, request, primaryKey); - if(!self._prevRequestRanges[primaryKey]) { - self._prevRequestRanges[primaryKey] = []; - } - self._prevRequestRanges[primaryKey].push({ - start: request.start, - end: request.start + data.photos.photo.length - }); - - //Iterate through the array of handlers, calling each one. - for(var i = 0; i < handlers.length; i++ ){ - doHandle(processedData, data, handlers[i]); - } - } - }; - - var data = this._prevRequests[requestKey]; - - //If the data was previously retrieved, there is no need to fetch it again. - if(data){ - this._handlers[requestKey] = null; - doHandle(this._cache[primaryKey], data, thisHandler); - return; - } else if(this._checkPrevRanges(primaryKey, request.start, request.count)) { - //If this range of data has already been retrieved, reuse it. - this._handlers[requestKey] = null; - doHandle(this._cache[primaryKey], null, thisHandler); - return; - } - - dojo.global[callbackFn] = function(data){ - myHandler(data); - //Clean up the function, it should never be called again - dojo.global[callbackFn] = null; - }; - - var deferred = dojo.io.script.get(getArgs); - - //We only set up the errback, because the callback isn't ever really used because we have - //to link to the jsonFlickrFeed function.... - deferred.addErrback(function(error){ - dojo.disconnect(handle); - errorHandler(error, request); - }); - }, - - getAttributes: function(item){ - // summary: - // See dojo.data.api.Read.getAttributes() - return ["title", "author", "imageUrl", "imageUrlSmall", - "imageUrlMedium", "imageUrlThumb", "link", - "dateTaken", "datePublished"]; - }, - - getValues: function(item, attribute){ - // summary: - // See dojo.data.api.Read.getValue() - this._assertIsItem(item); - this._assertIsAttribute(attribute); - if(attribute === "title"){ - return [this._unescapeHtml(item.title)]; // String - }else if(attribute === "author"){ - return [item.ownername]; // String - }else if(attribute === "imageUrlSmall"){ - return [item.media.s]; // String - }else if(attribute === "imageUrl"){ - return [item.media.l]; // String - }else if(attribute === "imageUrlMedium"){ - return [item.media.m]; // String - }else if(attribute === "imageUrlThumb"){ - return [item.media.t]; // String - }else if(attribute === "link"){ - return ["http://www.flickr.com/photos/" + item.owner + "/" + item.id]; // String - }else if(attribute === "dateTaken"){ - return item.datetaken; - }else if(attribute === "datePublished"){ - return item.datepublished; - } - - return undefined; - }, - - _processFlickrData: function(/* Object */data, /* Object */request, /* String */ cacheKey){ - // summary: Processes the raw data from Flickr and updates the internal cache. - // data: - // Data returned from Flickr - // request: - // The original dojo.data.Request object passed in by the user. - - //If the data contains an 'item' object, it has not come from the REST services, - //so process it using the FlickrStore. - if(data.items){ - return dojox.data.FlickrStore.prototype._processFlickrData.apply(this,arguments); - } - - var template = ["http://farm", null, ".static.flickr.com/", null, "/", null, "_", null]; - - var items = []; - if(data.stat == "ok" && data.photos && data.photos.photo){ - items = data.photos.photo; - - //Add on the store ref so that isItem can work. - for(var i = 0; i < items.length; i++){ - var item = items[i]; - item[this._storeRef] = this; - - template[1] = item.farm; - template[3] = item.server; - template[5] = item.id; - template[7] = item.secret; - - var base = template.join(""); - item.media = { - s: base + "_s.jpg", - m: base + "_m.jpg", - l: base + ".jpg", - t: base + "_t.jpg" - }; - } - } - var start = request.start ? request.start : 0; - var arr = this._cache[cacheKey]; - if(!arr) { - this._cache[cacheKey] = arr = []; - } - for(var count = 0; count < items.length; count++){ - arr[count + start] = items[count]; - } - - return arr; // Array - }, - - _checkPrevRanges: function(primaryKey, start, count) { - var end = start + count; - var arr = this._prevRequestRanges[primaryKey]; - if(!arr) { - return false; - } - for(var i = 0; i< arr.length; i++) { - if(start >= arr[i].start && - end <= arr[i].end) { - return true; - } - } - return false; - } -}); - - -} |