FlickrStore.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. define("dojox/data/FlickrStore", ["dojo/_base/lang", "dojo/_base/declare", "dojo/_base/array", "dojo/data/util/simpleFetch", "dojo/io/script",
  2. "dojo/_base/connect", "dojo/date/stamp", "dojo/AdapterRegistry"],
  3. function(lang, declare, array, simpleFetch, scriptIO, connect, dateStamp, AdapterRegistry) {
  4. var FlickrStore = declare("dojox.data.FlickrStore", null, {
  5. constructor: function(/*Object*/args){
  6. // summary:
  7. // Initializer for the FlickrStore store.
  8. // description:
  9. // The FlickrStore is a Datastore interface to one of the basic services
  10. // of the Flickr service, the public photo feed. This does not provide
  11. // access to all the services of Flickr.
  12. // This store cannot do * and ? filtering as the flickr service
  13. // provides no interface for wildcards.
  14. if(args && args.label){
  15. this.label = args.label;
  16. }
  17. if(args && "urlPreventCache" in args){
  18. this.urlPreventCache = args.urlPreventCache?true:false;
  19. }
  20. },
  21. _storeRef: "_S",
  22. label: "title",
  23. //Flag to allor control of if cache prevention is enabled or not.
  24. urlPreventCache: true,
  25. _assertIsItem: function(/* item */ item){
  26. // summary:
  27. // This function tests whether the item passed in is indeed an item in the store.
  28. // item:
  29. // The item to test for being contained by the store.
  30. if(!this.isItem(item)){
  31. throw new Error("dojox.data.FlickrStore: a function was passed an item argument that was not an item");
  32. }
  33. },
  34. _assertIsAttribute: function(/* attribute-name-string */ attribute){
  35. // summary:
  36. // This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
  37. // attribute:
  38. // The attribute to test for being contained by the store.
  39. if(typeof attribute !== "string"){
  40. throw new Error("dojox.data.FlickrStore: a function was passed an attribute argument that was not an attribute name string");
  41. }
  42. },
  43. getFeatures: function(){
  44. // summary:
  45. // See dojo.data.api.Read.getFeatures()
  46. return {
  47. 'dojo.data.api.Read': true
  48. };
  49. },
  50. getValue: function(item, attribute, defaultValue){
  51. // summary:
  52. // See dojo.data.api.Read.getValue()
  53. var values = this.getValues(item, attribute);
  54. if(values && values.length > 0){
  55. return values[0];
  56. }
  57. return defaultValue;
  58. },
  59. getAttributes: function(item){
  60. // summary:
  61. // See dojo.data.api.Read.getAttributes()
  62. return [
  63. "title", "description", "author", "datePublished", "dateTaken",
  64. "imageUrl", "imageUrlSmall", "imageUrlMedium", "tags", "link"
  65. ];
  66. },
  67. hasAttribute: function(item, attribute){
  68. // summary:
  69. // See dojo.data.api.Read.hasAttributes()
  70. var v = this.getValue(item,attribute);
  71. if(v || v === "" || v === false){
  72. return true;
  73. }
  74. return false;
  75. },
  76. isItemLoaded: function(item){
  77. // summary:
  78. // See dojo.data.api.Read.isItemLoaded()
  79. return this.isItem(item);
  80. },
  81. loadItem: function(keywordArgs){
  82. // summary:
  83. // See dojo.data.api.Read.loadItem()
  84. },
  85. getLabel: function(item){
  86. // summary:
  87. // See dojo.data.api.Read.getLabel()
  88. return this.getValue(item,this.label);
  89. },
  90. getLabelAttributes: function(item){
  91. // summary:
  92. // See dojo.data.api.Read.getLabelAttributes()
  93. return [this.label];
  94. },
  95. containsValue: function(item, attribute, value){
  96. // summary:
  97. // See dojo.data.api.Read.containsValue()
  98. var values = this.getValues(item,attribute);
  99. for(var i = 0; i < values.length; i++){
  100. if(values[i] === value){
  101. return true;
  102. }
  103. }
  104. return false;
  105. },
  106. getValues: function(item, attribute){
  107. // summary:
  108. // See dojo.data.api.Read.getValue()
  109. this._assertIsItem(item);
  110. this._assertIsAttribute(attribute);
  111. var u = lang.hitch(this, "_unescapeHtml");
  112. var s = lang.hitch(dateStamp, "fromISOString");
  113. switch(attribute){
  114. case "title":
  115. return [ u(item.title) ];
  116. case "author":
  117. return [ u(item.author) ];
  118. case "datePublished":
  119. return [ s(item.published) ];
  120. case "dateTaken":
  121. return [ s(item.date_taken) ];
  122. case "imageUrlSmall":
  123. return [ item.media.m.replace(/_m\./, "_s.") ];
  124. case "imageUrl":
  125. return [ item.media.m.replace(/_m\./, ".") ];
  126. case "imageUrlMedium":
  127. return [ item.media.m ];
  128. case "link":
  129. return [ item.link ];
  130. case "tags":
  131. return item.tags.split(" ");
  132. case "description":
  133. return [ u(item.description) ];
  134. default:
  135. return [];
  136. }
  137. },
  138. isItem: function(item){
  139. // summary:
  140. // See dojo.data.api.Read.isItem()
  141. if(item && item[this._storeRef] === this){
  142. return true;
  143. }
  144. return false;
  145. },
  146. close: function(request){
  147. // summary:
  148. // See dojo.data.api.Read.close()
  149. },
  150. _fetchItems: function(request, fetchHandler, errorHandler){
  151. // summary:
  152. // Fetch flickr items that match to a query
  153. // request:
  154. // A request object
  155. // fetchHandler:
  156. // A function to call for fetched items
  157. // errorHandler:
  158. // A function to call on error
  159. var rq = request.query = request.query || {};
  160. //Build up the content to send the request for.
  161. var content = {
  162. format: "json",
  163. tagmode:"any"
  164. };
  165. array.forEach(
  166. [ "tags", "tagmode", "lang", "id", "ids" ],
  167. function(i){
  168. if(rq[i]){ content[i] = rq[i]; }
  169. }
  170. );
  171. content.id = rq.id || rq.userid || rq.groupid;
  172. if(rq.userids){
  173. content.ids = rq.userids;
  174. }
  175. //Linking this up to Flickr is a PAIN!
  176. var handle = null;
  177. var getArgs = {
  178. url: dojox.data.FlickrStore.urlRegistry.match(request),
  179. preventCache: this.urlPreventCache,
  180. content: content
  181. };
  182. var myHandler = lang.hitch(this, function(data){
  183. if(!!handle){
  184. connect.disconnect(handle);
  185. }
  186. //Process the items...
  187. fetchHandler(this._processFlickrData(data), request);
  188. });
  189. handle = connect.connect("jsonFlickrFeed", myHandler);
  190. var deferred = scriptIO.get(getArgs);
  191. //We only set up the errback, because the callback isn't ever really used because we have
  192. //to link to the jsonFlickrFeed function....
  193. deferred.addErrback(function(error){
  194. connect.disconnect(handle);
  195. errorHandler(error, request);
  196. });
  197. },
  198. _processFlickrData: function(data){
  199. var items = [];
  200. if(data.items){
  201. items = data.items;
  202. //Add on the store ref so that isItem can work.
  203. for(var i = 0; i < data.items.length; i++){
  204. var item = data.items[i];
  205. item[this._storeRef] = this;
  206. }
  207. }
  208. return items;
  209. },
  210. _unescapeHtml: function(/*String*/ str){
  211. // summary:
  212. // Utility function to un-escape XML special characters in an
  213. // HTML string.
  214. // str: String.
  215. // The string to un-escape
  216. // returns:
  217. // HTML String converted back to the normal text (unescaped)
  218. // characters (<,>,&, ", etc,).
  219. //TODO:
  220. // Check to see if theres already compatible escape() in
  221. // dojo.string or dojo.html
  222. return str.replace(/&amp;/gm, "&").
  223. replace(/&lt;/gm, "<").
  224. replace(/&gt;/gm, ">").
  225. replace(/&quot;/gm, "\"").
  226. replace(/&#39;/gm, "'");
  227. }
  228. });
  229. lang.extend(FlickrStore, simpleFetch);
  230. var feedsUrl = "http://api.flickr.com/services/feeds/";
  231. var reg = FlickrStore.urlRegistry = new AdapterRegistry(true);
  232. reg.register("group pool",
  233. function(request){ return !!request.query["groupid"]; },
  234. feedsUrl+"groups_pool.gne"
  235. );
  236. reg.register("default",
  237. function(request){ return true; },
  238. feedsUrl+"photos_public.gne"
  239. );
  240. //We have to define this because of how the Flickr API works.
  241. //This somewhat stinks, but what can you do?
  242. if(!jsonFlickrFeed){
  243. var jsonFlickrFeed = function(data){};
  244. }
  245. return FlickrStore;
  246. });