PicasaStore.js 7.5 KB

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