a:27:{s:9:"#provides";s:26:"dojox.data.FlickrRestStore";s:9:"#resource";s:23:"data/FlickrRestStore.js";s:9:"#requires";a:1:{i:0;a:2:{i:0;s:6:"common";i:1;s:22:"dojox.data.FlickrStore";}}s:26:"dojox.data.FlickrRestStore";a:7:{s:4:"type";s:8:"Function";s:6:"chains";a:2:{s:9:"prototype";a:1:{i:0;s:22:"dojox.data.FlickrStore";}s:4:"call";a:1:{i:0;s:22:"dojox.data.FlickrStore";}}s:10:"parameters";a:1:{s:4:"args";a:1:{s:4:"type";s:6:"Object";}}s:6:"source";s:317:" if(args){ 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++;";s:7:"summary";s:42:"Initializer for the FlickrRestStore store.";s:11:"description";s:278:"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.";s:9:"classlike";b:1;}s:30:"dojox.data.FlickrRestStore._id";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:7:"Integer";s:7:"summary";s:35:"A unique identifier for this store.";s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;}s:40:"dojox.data.FlickrRestStore._requestCount";a:4:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:7:"Integer";s:7:"summary";s:109:"A counter for the number of requests made. This is used to define the callback function that Flickr will use.";s:7:"private";b:1;}s:41:"dojox.data.FlickrRestStore._flickrRestUrl";a:4:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"String";s:7:"summary";s:36:"The URL to the Flickr REST services.";s:7:"private";b:1;}s:34:"dojox.data.FlickrRestStore._apikey";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"String";s:7:"summary";s:65:"The users API key to be used when accessing Flickr REST services.";s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;}s:36:"dojox.data.FlickrRestStore._storeRef";a:4:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"String";s:7:"summary";s:65:"A key used to mark an data store item as belonging to this store.";s:7:"private";b:1;}s:33:"dojox.data.FlickrRestStore._cache";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:5:"Array";s:7:"summary";s:51:"An Array of all previously downloaded picture info.";s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;}s:40:"dojox.data.FlickrRestStore._prevRequests";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"Object";s:7:"summary";s:92:"A HashMap used to record the signature of a request to prevent duplicate request being made.";s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;}s:36:"dojox.data.FlickrRestStore._handlers";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"Object";s:7:"summary";s:333:"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.";s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;}s:42:"dojox.data.FlickrRestStore._sortAttributes";a:4:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:6:"Object";s:7:"private";b:1;s:7:"summary";s:0:"";}s:38:"dojox.data.FlickrRestStore._fetchItems";a:6:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:7:"request";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:16:"A request object";}s:12:"fetchHandler";a:2:{s:4:"type";s:8:"Function";s:7:"summary";s:36:"A function to call for fetched items";}s:12:"errorHandler";a:2:{s:4:"type";s:8:"Function";s:7:"summary";s:27:"A function to call on error";}}s:6:"source";s:8955:" var query = {}; if(!request.query){ request.query = query = {}; } else { dojo.mixin(query, request.query); } var primaryKey = []; var secondaryKey = []; //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" }; 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 if(content.api_key){ isRest = true; request.query.apikey = content.api_key; secondaryKey.push("api"+content.api_key); }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.setid; primaryKey.push("set" + request.query.setid); } 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 handle = null; var getArgs = { url: this._flickrRestUrl, preventCache: true, content: content, callbackParamName: "jsoncallback" }; var doHandle = dojo.hitch(this, 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){ var photos = null; if(data){ photos = (data.photoset ? data.photoset : data.photos); } if(photos && typeof(photos.perpage) != "undefined" && typeof(photos.pages) != "undefined"){ if(photos.perpage * 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 + 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 = photos.perpage * photos.pages; } this._maxPhotosPerUser[primaryKey] = maxPhotos; onBegin(maxPhotos, handler.request); }else if(this._maxPhotosPerUser[primaryKey]){ onBegin(this._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 = dojo.hitch(this, 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 = this._handlers[requestKey]; if(!handlers){ console.log("FlickrRestStore: no handlers for data", data); return; } this._handlers[requestKey] = null; this._prevRequests[requestKey] = data; //Process the data once. var processedData = this._processFlickrData(data, request, primaryKey); if(!this._prevRequestRanges[primaryKey]){ this._prevRequestRanges[primaryKey] = []; } this._prevRequestRanges[primaryKey].push({ start: request.start, end: request.start + (data.photoset ? data.photoset.photo.length : data.photos.photo.length) }); //Iterate through the array of handlers, calling each one. dojo.forEach(handlers, function(i){ doHandle(processedData, data, 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; } var deferred = dojo.io.script.get(getArgs); deferred.addCallback(myHandler); //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); });";s:7:"summary";s:40:"Fetch flickr items that match to a query";s:7:"private";b:1;}s:40:"dojox.data.FlickrRestStore.getAttributes";a:5:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:8:"Function";s:10:"parameters";a:1:{s:4:"item";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:142:" return [ "title", "author", "imageUrl", "imageUrlSmall", "imageUrlMedium", "imageUrlThumb", "link", "dateTaken", "datePublished" ]; ";s:7:"summary";s:38:"See dojo.data.api.Read.getAttributes()";}s:36:"dojox.data.FlickrRestStore.getValues";a:6:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:8:"Function";s:10:"parameters";a:2:{s:4:"item";a:1:{s:4:"type";s:0:"";}s:9:"attribute";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:726:" this._assertIsItem(item); this._assertIsAttribute(attribute); switch(attribute){ case "title": return [ this._unescapeHtml(item.title) ]; // String case "author": return [ item.ownername ]; // String case "imageUrlSmall": return [ item.media.s ]; // String case "imageUrl": return [ item.media.l ]; // String case "imageUrlMedium": return [ item.media.m ]; // String case "imageUrlThumb": return [ item.media.t ]; // String case "link": return [ "http://www.flickr.com/photos/" + item.owner + "/" + item.id ]; // String case "dateTaken": return [ item.datetaken ]; case "datePublished": return [ item.datepublished ]; default: return undefined; }";s:7:"summary";s:33:"See dojo.data.api.Read.getValue()";s:7:"returns";s:72:"String|www.flickr.com/photos/" + item.owner + "/" + item.id ]; // String";}s:45:"dojox.data.FlickrRestStore._processFlickrData";a:8:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:4:"data";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:25:"Data returned from Flickr";}s:7:"request";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:177:"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.";}s:8:"cacheKey";a:1:{s:4:"type";s:6:"String";}}s:6:"source";s:1130:" 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 = []; var photos = (data.photoset ? data.photoset : data.photos); if(data.stat == "ok" && photos && photos.photo){ items = 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" }; if(!item.owner && data.photoset){ item.owner = data.photoset.owner; } } } var start = request.start ? request.start : 0; var arr = this._cache[cacheKey]; if(!arr){ this._cache[cacheKey] = arr = []; } dojo.forEach(items, function(i, idx){ arr[idx+ start] = i; }); return arr; // Array";s:7:"summary";s:66:"Processes the raw data from Flickr and updates the internal cache.";s:7:"returns";s:5:"Array";s:6:"chains";a:1:{s:4:"call";a:1:{i:0;s:51:"dojox.data.FlickrStore.prototype._processFlickrData";}}s:7:"private";b:1;}s:43:"dojox.data.FlickrRestStore._checkPrevRanges";a:6:{s:9:"prototype";s:26:"dojox.data.FlickrRestStore";s:4:"type";s:8:"Function";s:10:"parameters";a:3:{s:10:"primaryKey";a:1:{s:4:"type";s:0:"";}s:5:"start";a:1:{s:4:"type";s:0:"";}s:5:"count";a:1:{s:4:"type";s:0:"";}}s:6:"source";s:186:" var end = start + count; var arr = this._prevRequestRanges[primaryKey]; return (!!arr) && dojo.some(arr, function(item){ return ((start >= item.start)&&(end <= item.end)); });";s:7:"private";b:1;s:7:"summary";s:0:"";}s:54:"dojox.data.FlickrRestStore._sortAttributes.date-posted";a:2:{s:14:"private_parent";b:1;s:7:"summary";s:0:"";}s:53:"dojox.data.FlickrRestStore._sortAttributes.date-taken";a:2:{s:14:"private_parent";b:1;s:7:"summary";s:0:"";}s:58:"dojox.data.FlickrRestStore._sortAttributes.interestingness";a:2:{s:14:"private_parent";b:1;s:7:"summary";s:0:"";}s:32:"dojox.data.FlickrRestStore.label";a:2:{s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"summary";s:0:"";}s:45:"dojox.data.FlickrRestStore._prevRequestRanges";a:3:{s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:44:"dojox.data.FlickrRestStore._maxPhotosPerUser";a:3:{s:8:"instance";s:26:"dojox.data.FlickrRestStore";s:7:"private";b:1;s:7:"summary";s:0:"";}s:5:"query";a:2:{s:6:"mixins";a:1:{s:6:"normal";a:1:{i:0;s:13:"request.query";}}s:7:"summary";s:0:"";}s:10:"dojox.data";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}s:5:"dojox";a:2:{s:4:"type";s:6:"Object";s:7:"summary";s:0:"";}}