1 /** 2 * @constructor Ajax implentation of a request processor - still very basic : more to flesh here 3 * @private 4 * Used by RequestProcessor 5 */ 6 if (typeof(MyOpenSpace.Ajax) == "undefined") MyOpenSpace.Ajax = {}; 7 8 /** 9 * Ajax is the XMLHTTP implementation for fetching REST data. 10 * HTTP stack has a limit of 2 XHR requests at a time, so we will be operating serially - one for API, one for content 11 * Leveraged by RequestProcessor 12 * @class 13 * @name MyOpenSpace.Ajax 14 * @private 15 */ 16 MyOpenSpace.Ajax = { 17 /** 18 * getConnection will return a valid XMLHttpRequest object, determined by browser capabilities. 19 * @function 20 * @return {XMLHttpRequest} A valid XMLHttpRequest object as supported by client's browser OR false if no XmlHttpRequest objects were created. 21 * @private 22 */ 23 getConnection: function() { 24 return Try.these( 25 function() { return new XMLHttpRequest() }, 26 function() { return new ActiveXObject("MSXML2.XMLHTTP.3.0") }, 27 function() { return new ActiveXObject("Msxml2.XMLHTTP") }, 28 function() { return new ActiveXObject("Microsoft.XMLHTTP") } 29 ) || false; 30 }, 31 32 /** 33 * connection is the internal connection object for content requests. 34 * not instantiated until getConnection is invoked. 35 * @private 36 */ 37 contentConnection: [], 38 /** 39 * activeContentConnections stops duplicate url/params/method calls to allow polling mechanisms to only occupy one connection 40 * @type Number 41 * @private 42 */ 43 activeContentConnections: [], 44 /** 45 * openConnections holds the current number of connections in use by the Ajax class. 46 * @type Number 47 * @private 48 */ 49 openConnections: 0, 50 /** 51 * openConnections holds the current number of connections in use by the Ajax class. 52 * @type Number 53 * @private 54 */ 55 openContentConnections: 0, 56 /** 57 * connection is the internal connection object. 58 * not instantiated until getConnection is invoked. 59 * @private 60 */ 61 connection: [], 62 63 /** 64 * async determines if the Ajax request will be asynchronous or not. 65 * @type Boolean 66 * @private 67 */ 68 async: true, 69 Completed: [], 70 Errored: [], 71 content_Completed: [], 72 content_Errored: [], 73 74 /** 75 * sendRequest will dispatch a request using XmlHttpRequest and execute the completion or error callback upon return. 76 * @param {opensocial.DataRequest} dataRequest The DataRequest associated with this call. 77 * @param {String} key The unique key name to associate the DataRequest and DataResponse. 78 * @param {function} onComplete The function to execute when the call completes. 79 * @param {function} onError The function to execute when the call results in an error 80 * @param {Boolean} async Sets the mode for XmlHttpRequest; true = asyncronous / false = syncronous 81 * @private 82 */ 83 sendRequest: function(dataRequest, type, onComplete, onError, async, opt_key) { 84 var key = opt_key ? opt_key : type; 85 86 this.Completed[key] = onComplete; 87 this.Errored[key] = onError; 88 if (async == null) async = true; 89 var ptr = this; 90 this.connection[key] = this.getConnection(); 91 92 try { 93 this.connection[key].open(dataRequest.method, dataRequest.endPoint, async); 94 this.connection[key].setRequestHeader("X-OpenSocial-Authorization", "OPENSOCIAL opensocial_token=\"" + dataRequest.osToken_ + "\""); 95 this.connection[key].setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 96 this.connection[key].setRequestHeader("Content-length", dataRequest.params.length); 97 this.connection[key].setRequestHeader("Connection", "close"); 98 this.connection[key].onreadystatechange = function() { ptr.readyStateChanged(type, key, opt_key) }; 99 100 this.connection[key].send(dataRequest.params); 101 102 } 103 catch (err) { 104 // Permission denied, not implemented, etc 105 this.Errored[key]({ "errorCode": opensocial.ResponseItem.Error.INTERNAL_ERROR, "errorMessage": err }, opt_key); //TODO: or is this BAD_REQUEST? 106 } 107 }, 108 109 /** 110 * sendContentRequest will dispatch a request to a third party server using XmlHttpRequest and execute the completion or error callback upon return. 111 * @param {String} url The URL to retrieve content from 112 * @param {Function} callback The function to call with the data from the URL once it is fetched 113 * @param {Map.<String, Object>} params Additional parameters to pass to the request 114 * 115 * @private 116 */ 117 sendContentRequest: function(url, onComplete, onError, params) { 118 var block = false; 119 120 for (var i = 0; i < this.activeContentConnections.length; i++) { 121 if (this.activeContentConnections[i].url === url) { 122 if (this.activeContentConnections[i].params.authType !== params.authType) break; 123 if (this.activeContentConnections[i].params.contentType !== params.contentType) break; 124 if (this.activeContentConnections[i].params.method !== params.method) break; 125 if (this.activeContentConnections[i].params.postData !== params.postData) break; 126 if (this.activeContentConnections[i].params.postDataLength !== params.postDataLength) break; 127 if (this.activeContentConnections[i].params.headers !== params.headers) break; 128 if (this.activeContentConnections[i].params.numEntries !== params.numEntries) break; 129 if (this.activeContentConnections[i].params.summariesOnly !== params.summariesOnly) break; 130 131 block = true; 132 } 133 } 134 if (!!block) return; 135 136 var keyDate = new Date(); 137 var contentConnectionID = keyDate.getTime(); 138 139 if (url.indexOf("?") > 0) { 140 url += "&ts=" + contentConnectionID; 141 } 142 else { 143 url = "?ts=" + contentConnectionID; 144 } 145 146 this.activeContentConnections.push({ url: url, params: params }); 147 148 while (this.contentConnection[contentConnectionID] != null) { contentConnectionID = contentConnectionID + "_"; } 149 this.contentConnection[contentConnectionID] = this.getConnection(); 150 151 this.content_Completed[contentConnectionID] = onComplete; 152 this.content_Errored[contentConnectionID] = onError; 153 var ptr = this; 154 try { 155 this.contentConnection[contentConnectionID].open(params.method, url, true); 156 157 if (params.headers != null) { 158 for (var i in params.headers) { 159 this.contentConnection[contentConnectionID].setRequestHeader(i, params.headers[i]); 160 } 161 } 162 163 this.contentConnection[contentConnectionID].setRequestHeader("Content-type", "application/x-www-form-urlencoded"); 164 this.contentConnection[contentConnectionID].setRequestHeader("Content-Length", params.postDataLength); 165 this.contentConnection[contentConnectionID].setRequestHeader("Connection", "close"); 166 this.contentConnection[contentConnectionID].onreadystatechange = function() { ptr.content_readyStateChanged(url, params, contentConnectionID) }; 167 this.contentConnection[contentConnectionID].send(params.postData); 168 } 169 catch (err) { 170 this.contentConnection[contentConnectionID] = null; 171 delete this.contentConnection[contentConnectionID]; 172 // Permission denied, not implemented, etc 173 this.content_Errored({ "errorCode": opensocial.ResponseItem.Error.INTERNAL_ERROR, "errorMessage": err }); //TODO: or is this BAD_REQUEST? 174 } 175 }, 176 177 /** 178 * content_readyStateChanged is the event handler for when the XmlHttpRequest's state changes when requesting outside the container API endpoints. 179 * @param {String} url The url associated with the content 180 * @private 181 */ 182 content_readyStateChanged: function(url, params, contentConnectionID) { 183 if (this.contentConnection[contentConnectionID].readyState === 4) { 184 var status, statusText; 185 try { 186 statusText = this.contentConnection[contentConnectionID].statusText; 187 status = this.contentConnection[contentConnectionID].status; 188 } 189 catch (err) { 190 statusText = "An error occurred."; 191 status = 500; 192 } 193 if (status === 200) { 194 for (var i = 0; i < this.activeContentConnections.length; i++) { 195 if (this.activeContentConnections[i].url === url) { 196 if (this.activeContentConnections[i].params.authType !== params.authType) break; 197 if (this.activeContentConnections[i].params.contentType !== params.contentType) break; 198 if (this.activeContentConnections[i].params.method !== params.method) break; 199 if (this.activeContentConnections[i].params.postData !== params.postData) break; 200 if (this.activeContentConnections[i].params.postDataLength !== params.postDataLength) break; 201 if (this.activeContentConnections[i].params.headers !== params.headers) break; 202 if (this.activeContentConnections[i].params.numEntries !== params.numEntries) break; 203 if (this.activeContentConnections[i].params.summariesOnly !== params.summariesOnly) break; 204 205 this.activeContentConnections.splice(i, 1); 206 } 207 } 208 209 var response = {}; 210 response.responseXML = this.contentConnection[contentConnectionID].responseXML; 211 response.responseText = this.contentConnection[contentConnectionID].responseText; 212 response.readyState = this.contentConnection[contentConnectionID].readyState; 213 response.status = status; 214 response.connectionID = contentConnectionID; 215 this.contentConnection[contentConnectionID] = null; 216 delete this.contentConnection[contentConnectionID]; 217 this.content_Completed[contentConnectionID](response, url, params); 218 } 219 else { 220 var error = this.getResponseError_(status, statusText); 221 this.contentConnection[contentConnectionID] = null; 222 delete this.contentConnection[contentConnectionID]; 223 this.content_Errored[contentConnectionID](error); 224 } 225 } 226 }, 227 /** 228 * getResponseError_ Create an error object mapping the status code to the matching 229 * ResponseItem.Error value. 230 * @param {integer} statusCode response status code 231 * @param {String} statusDescription response status description 232 * @private 233 */ 234 getResponseError_: function(statusCode, statusDescription) { 235 var errorCode; 236 if ("undefined" !== typeof (opensocial)) { 237 switch (statusCode) { 238 case 400: 239 errorCode = opensocial.ResponseItem.Error.BAD_REQUEST; 240 break; 241 case 403: 242 errorCode = opensocial.ResponseItem.Error.FORBIDDEN; 243 break; 244 case 501: 245 errorCode = opensocial.ResponseItem.Error.NOT_IMPLEMENTED; 246 break; 247 case 401: 248 errorCode = opensocial.ResponseItem.Error.UNAUTHORIZED; 249 break; 250 default: 251 errorCode = opensocial.ResponseItem.Error.INTERNAL_ERROR; 252 break; 253 } 254 } 255 else { 256 errorCode = "Document is probably unloading."; 257 } 258 var error = { "errorCode": errorCode, "errorMessage": statusDescription }; 259 return error; 260 }, 261 /** 262 * readyStateChanged is the event handler for when the XmlHttpRequest's state changes. 263 * @param {String} key The unique key name to associate the DataRequest and DataResponse. 264 * @private 265 */ 266 readyStateChanged: function(type, key, opt_key) { 267 if (this.connection[key].readyState === 4) { 268 var status, statusText; 269 try { 270 statusText = this.connection[key].statusText; 271 status = this.connection[key].status; 272 } 273 catch (err) { 274 statusText = "An error occurred."; 275 status = 500; 276 } 277 if (200 === status || 201 === status) { 278 var response = {}; 279 response.responseXML = this.connection[key].responseXML; 280 response.responseText = this.connection[key].responseText; 281 282 this.connection[key] = null; 283 delete this.connection[key]; 284 this.Completed[key](response, type, opt_key); 285 } 286 else { 287 var error = this.getResponseError_(status, statusText); 288 this.Errored[key](error, opt_key); 289 } 290 } 291 } 292 };/* ================================================================ 293 * MyOpenSpace.Album 294 * ================================================================ 295 */ 296 297 /** 298 * A class representing an album. 299 * @constructor 300 * @private 301 * @name MyOpenSpace.Album 302 */ 303 MyOpenSpace.Album = function() {}; 304 /** 305 * The fields for MyOpenSpace.Album 306 * @class 307 * @name MyOpenSpace.Album.Field 308 * @static 309 */ 310 MyOpenSpace.Album.Field = { 311 /** 312 * A number representing an Album's unique identifier. 313 * @memberOf MyOpenSpace.Album.Field 314 */ 315 ALBUM_ID:"ALBUM_ID", 316 317 /** 318 * The RESTFUL URI with which to access the album on the API. 319 * @memberOf MyOpenSpace.Album.Field 320 */ 321 ALBUM_URI:"ALBUM_URI", 322 323 /** 324 * The album's title. 325 * @memberOf MyOpenSpace.Album.Field 326 */ 327 TITLE:"TITLE", 328 329 /** 330 * The geographic location where the album's pictures were taken. 331 * @memberOf MyOpenSpace.Album.Field 332 */ 333 LOCATION:"LOCATION", 334 335 /** 336 * A URL for the album's default image. 337 * @memberOf MyOpenSpace.Album.Field 338 */ 339 DEFAULT_IMAGE:"DEFAULT_IMAGE", 340 341 /** 342 * A string representing the album's privacy setting, such as "Public" or "Private" 343 * @memberOf MyOpenSpace.Album.Field 344 */ 345 PRIVACY:"PRIVACY", 346 347 /** 348 * An integer representing the total number of photos in the album (not the number of photos actually contained within the current object). 349 * @memberOf MyOpenSpace.Album.Field 350 */ 351 PHOTO_COUNT:"PHOTO_COUNT", 352 353 /** 354 * A RESTFUL URI with which to access the photos contained in the album. 355 * @memberOf MyOpenSpace.Album.Field 356 */ 357 PHOTOS_URI:"PHOTOS_URI" 358 }; 359 360 /** 361 * Returns the field specified by key 362 * @param {String} key The key to search by 363 * @return {MyOpenSpace.Album || undefined} The album if found, nothing otherwise. 364 */ 365 MyOpenSpace.Album.prototype.getField = function(key) { return this[key]; }; 366 /** 367 * Writes a value to the field specified by the key 368 * @param {String} key The key to search by. 369 * @param {String} val The value to set. 370 * @private 371 * @private 372 */ 373 MyOpenSpace.Album.prototype.setField_ = function(key,val) { this[key] = val; };/* ================================================================ 374 * MyOpenSpace.Application 375 * ================================================================ 376 */ 377 378 /** 379 * A class representing an Application. 380 * @constructor 381 * @name MyOpenSpace.Application 382 * @private 383 */ 384 MyOpenSpace.Application = function(opt_params){ 385 this.fields_ = opt_params || {}; 386 }; 387 /** 388 * @static 389 * @class 390 * All of the fields that a Application has. These are the supported keys for the 391 * <a href="MyOpenSpace.Application.html#getField">Application.getField()</a> method. 392 * 393 * @name MyOpenSpace.Application.Field 394 */ 395 MyOpenSpace.Application.Field = { 396 /** 397 * A string ID that can be permanently associated with this Application. 398 * @member MyOpenSpace.Application.Field 399 */ 400 ID : 'ID', 401 402 /** 403 * A opensocial.Name object containing the Application's name. 404 * @member MyOpenSpace.Application.Field 405 */ 406 NAME : 'NAME', 407 408 /** 409 * Application's small icon URL, as a string. 410 * This URL must be fully qualified. Relative URLs will not work in gadgets. 411 * @member MyOpenSpace.Application.Field 412 */ 413 ICON_SMALL : 'ICON_SMALL', 414 415 /** 416 * Application's large icon URL, as a string. 417 * This URL must be fully qualified. Relative URLs will not work in gadgets. 418 * @member MyOpenSpace.Application.Field 419 */ 420 ICON_LARGE : 'ICON_LARGE', 421 422 /** 423 * Application's profile URL, specified as a String. 424 * This URL must be fully qualified. Relative URLs will not work in gadgets. 425 * Not supported by all containers. 426 * @member MyOpenSpace.Application.Field 427 */ 428 PROFILE_URL : 'PROFILE_URL', 429 430 /** 431 * Application's installation URL, specified as a String. 432 * This URL must be fully qualified. Relative URLs will not work in gadgets. 433 * Not supported by all containers. 434 * @member MyOpenSpace.Application.Field 435 */ 436 INSTALL_URL : 'INSTALL_URL', 437 438 /** 439 * URLs related to the Application, their webpages, or feeds. Specified as an 440 * Array of opensocial.Url. 441 * Not supported by all containers. 442 * 443 * @member MyOpenSpace.Application.Field 444 */ 445 URLS : 'URLS', 446 447 /** 448 * Url of the canvas page 449 * 450 * @member MyOpenSpace.Application.Field 451 */ 452 453 CANVAS_URL : 'CANVAS_URL', 454 455 /** 456 * Arbitrary tags about the application, specified as an Array of Strings. 457 * Not supported by all containers. 458 * 459 * @member MyOpenSpace.Application.Field 460 */ 461 TAGS : 'TAGS' 462 463 }; 464 465 466 /** 467 * Gets the activity data that's associated with the specified key. 468 * 469 * @param {String} key The key to get data for; 470 * see the <a href="MyOpenSpace.Application.Field.html">Field</a> class 471 * for possible values 472 * @return {String} The data 473 * @member MyOpenSpace.Application 474 */ 475 MyOpenSpace.Application.prototype.getField = function(key) { 476 return this.fields_[key]; 477 }; 478 479 480 /** 481 * Sets data for this activity associated with the given key. 482 * 483 * @param {String} key The key to set data for 484 * @param {String} data The data to set 485 */ 486 MyOpenSpace.Application.prototype.setField = function(key, data) { 487 return this.fields_[key] = data; 488 }; 489 490 491 /** 492 * Gets an ID that can be permanently associated with this application. 493 * 494 * @return {String} The ID 495 * @member MyOpenSpace.Application 496 */ 497 MyOpenSpace.Application.prototype.getId = function() { 498 return this.getField(MyOpenSpace.Application.Field.ID); 499 }; 500 501 /** 502 * Gets the display name for this application 503 * 504 * @return {String} The Display Name 505 * @member MyOpenSpace.Application 506 */ 507 MyOpenSpace.Application.prototype.getDisplayName = function() { 508 return this.getField(MyOpenSpace.Application.Field.NAME); 509 };/** 510 * Copyright 2007 Fox Interactive Media 511 * <DISCLAIMER HERE> 512 * @fileoverview Interface for container and associated classes; everything needed to query/update MySpace API data via OpenSocial interface. 513 * 514 * @author mnewbould [_at_] myspace [_dot_] com (Max Newbould) 515 * @author crussell [_at_] myspace [_dot_] com (Chad Russell) 516 * @author jreyes [_at_] myspace [_dot_] com (Jorge Reyes) 517 * @author jmay [_at_] myspace [_dot_] com (Justin May) 518 */ 519 520 if (typeof(MyOpenSpace) == "undefined") 521 /** 522 * Namespace for top level MyOpenSpace functions. 523 * @constructor (note: a constructor for JsDoc purposes) 524 */ 525 MyOpenSpace = { Version: "0.8" }; 526 /** 527 * @private 528 */ 529 MyOpenSpace.PrefetchParameters = { params_: {} }; 530 /** 531 * 532 * @param {Object} key 533 * @param {Object} value 534 * @private 535 */ 536 MyOpenSpace.PrefetchParameters.registerParam = function(key, value) { 537 this.params_[key] = value; 538 //gadgets.views.getParams()[key] = value; 539 }; 540 /** 541 * @private 542 */ 543 MyOpenSpace.PrefetchParameters.syncParams = function() { 544 for (var key in this.params_) { 545 if (typeof(gadgets.views.getParams()[key]) === "undefined") gadgets.views.getParams()[key] = this.params_[key]; 546 } 547 }; 548 /** 549 * 550 * @param {Object} key 551 * @private 552 */ 553 MyOpenSpace.PrefetchParameters.getParam = function(key) { 554 if (typeof (gadgets.views.getParams()[key]) !== "undefined") { 555 return gadgets.views.getParams()[key]; 556 } else { 557 return this.params_[key]; 558 } 559 }; 560 561 /** 562 * Defines the default page size for paginated requests. 563 * Used as max/default for MAX of pagination. 564 * @static 565 * @constant 566 */ 567 MyOpenSpace.DefaultPageSize = 20; 568 569 /** 570 * Defines the type of idSpec mapping value 571 * @static 572 * @class 573 * @name MyOpenSpace.IdSpecMapping_ 574 * @constructor (note: a constructor for JsDoc purposes) 575 * @private 576 */ 577 MyOpenSpace.IdSpecMapping_ = { 578 /** 579 * The idSpec mapping for viewer friends. 580 * @memberOf MyOpenSpace.IdSpecMapping_ 581 * @constant 582 * @private 583 */ 584 VIEWER_FRIENDS:"VIEWER_FRIENDS", 585 586 /** 587 * The idSpec mapping for owner friends. 588 * @memberOf MyOpenSpace.IdSpecMapping_ 589 * @constant 590 * @private 591 */ 592 OWNER_FRIENDS:"OWNER_FRIENDS", 593 /** 594 * The idSpec mapping for viewer. 595 * @memberOf MyOpenSpace.IdSpecMapping_ 596 * @constant 597 * @private 598 */ 599 VIEWER : "VIEWER", 600 /** 601 * The idSpec mapping for owner. 602 * @memberOf MyOpenSpace.IdSpecMapping_ 603 * @constant 604 * @private 605 */ 606 OWNER : "OWNER" 607 }; 608 609 /** 610 * <p>Enumerates the types of requests that can be made.</p> 611 * <p>It is used to retreive ResponseItems if opt_key was not 612 * set when adding the request.</p> 613 * <p> 614 * If more that one request of the same type is made, the first item can be retrieve 615 * directly using the enumeration value, the rest will have a "_#" postfix added 616 * to the enumeration value where # will be a sequential number starting with 1.</p> 617 * @static 618 * @class 619 * @name MyOpenSpace.RequestType 620 * @example 621 * var container = opensocial.Container.get(); 622 * var request = this.container.newDataRequest(); 623 * var fetchViewer = request.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER); 624 * var fetchOwner = request.newFetchPersonRequest(opensocial.IdSpec.PersonId.OWNER); 625 * request.add(fetchViewer); // opt_key not set 626 * request.add(fetchOwner); // opt_key not set 627 * request.send(callback); 628 * function callback(response){ 629 * var viewer = response.get(MyOpenSpace.RequestType.FETCH_PERSON); 630 * var owner = response.get(MyOpenSpace.RequestType.FETCH_PERSON + “_1”); 631 * } 632 */ 633 MyOpenSpace.RequestType = { 634 /** 635 * Default key to retreive the opensocial.ResponseItem from an 636 * opensocial.newFetchPerson. 637 * @memberOf MyOpenSpace.RequestType 638 * @constant 639 */ 640 FETCH_PERSON:"FETCH_PERSON", 641 /** 642 * Default key to retreive the opensocial.ResponseItem from an 643 * opensocial.DataRequest.newFetchPeople. 644 * @memberOf MyOpenSpace.RequestType 645 * @constant 646 */ 647 FETCH_PEOPLE:"FETCH_PEOPLE", 648 /** 649 * Default key to retreive the opensocial.ResponseItem from an 650 * opensocial.DataRequest.newFetchPersonAppDataRequest. 651 * @memberOf MyOpenSpace.RequestType 652 * @constant 653 */ 654 FETCH_PERSON_DATA:"FETCH_PERSON_DATA", 655 /** 656 * Default key to retreive the opensocial.ResponseItem from an 657 * opensocial.DataRequest.newFetchPersonAppDataRequest. 658 * @memberOf MyOpenSpace.RequestType 659 * @constant 660 */ 661 UPDATE_PERSON_DATA:"UPDATE_PERSON_DATA", 662 /** 663 * Default key to retreive the opensocial.ResponseItem from an 664 * opensocial.DataRequest.newRemovePersonAppDataRequest. 665 * @memberOf MyOpenSpace.RequestType 666 * @constant 667 */ 668 REMOVE_PERSON_DATA:"REMOVE_PERSON_DATA", 669 /** 670 * Default key to retreive the opensocial.ResponseItem from an 671 * opensocial.DataRequest.newFetchActivitiesRequest. 672 * @memberOf MyOpenSpace.RequestType 673 * @constant 674 */ 675 FETCH_ACTIVITIES:"FETCH_ACTIVITIES", 676 /** 677 * Default key to retreive the opensocial.ResponseItem from an 678 * MyOpenSpace.DataRequest.newFetchAlbumsRequest. 679 * @memberOf MyOpenSpace.RequestType 680 * @constant 681 */ 682 FETCH_ALBUMS:"FETCH_ALBUMS", 683 /** 684 * Default key to retreive the opensocial.ResponseItem from an 685 * MyOpenSpace.DataRequest.newFetchAlbumRequest. 686 * @memberOf MyOpenSpace.RequestType 687 * @constant 688 */ 689 FETCH_ALBUM:"FETCH_ALBUM", 690 /** 691 * Default key to retreive the opensocial.ResponseItem from an 692 * MyOpenSpace.DataRequest.newFetchVideosRequest. 693 * @memberOf MyOpenSpace.RequestType 694 * @constant 695 */ 696 FETCH_VIDEOS:"FETCH_VIDEOS", 697 /** 698 * Default key to retreive the opensocial.ResponseItem from an 699 * MyOpenSpace.DataRequest.newFetchVideoRequest. 700 * @memberOf MyOpenSpace.RequestType 701 * @constant 702 */ 703 FETCH_VIDEO:"FETCH_VIDEO", 704 /** 705 * Default key to retreive the opensocial.ResponseItem from an 706 * MyOpenSpace.DataRequest.newFetchPhotosRequest. 707 * @memberOf MyOpenSpace.RequestType 708 * @constant 709 */ 710 FETCH_PHOTOS:"FETCH_PHOTOS", 711 /** 712 * Default key to retreive the opensocial.ResponseItem from an 713 * MyOpenSpace.DataRequest.newFetchPhotoRequest. 714 * @memberOf MyOpenSpace.RequestType 715 * @constant 716 */ 717 FETCH_PHOTO:"FETCH_PHOTO", 718 /** 719 * Default key to retreive the opensocial.ResponseItem from an 720 * MyOpenSpace.DataRequest.newFetchIndicatorsRequest. 721 * @memberOf MyOpenSpace.RequestType 722 * @constant 723 */ 724 FETCH_INDICATORS:"FETCH_INDICATORS", 725 726 /** 727 * Default key to retreive the opensocial.ResponseItem from an 728 * MyOpenSpace.DataRequest.newFetchPersonStatusRequest. 729 * @memberOf MyOpenSpace.RequestType 730 * @constant 731 */ 732 FETCH_PERSON_STATUS:"FETCH_PERSON_STATUS", 733 734 /** 735 * Default key to retreive the opensocial.ResponseItem from an 736 * MyOpenSpace.DataRequest.newFetchPersonMoodRequest. 737 * @memberOf MyOpenSpace.RequestType 738 * @constant 739 */ 740 FETCH_PERSON_MOOD:"FETCH_PERSON_MOOD", 741 742 /** 743 * Default key to retreive the opensocial.ResponseItem from an 744 * MyOpenSpace.DataRequest.newPeopleFriendshipRequest. 745 * @memberOf MyOpenSpace.RequestType 746 * @constant 747 */ 748 FETCH_PEOPLE_FRIENDSHIP: "FETCH_PEOPLE_FRIENDSHIP", 749 750 /** 751 * Default key to retreive the opensocial.ResponseItem from an 752 * MyOpenSpace.DataRequest.newPersonFriendshipRequest. 753 * @memberOf MyOpenSpace.RequestType 754 * @constant 755 */ 756 FETCH_PERSON_FRIENDSHIP: "FETCH_PERSON_FRIENDSHIP" 757 }; 758 if (typeof(MyOpenSpace.ClientLibraries) == "undefined") MyOpenSpace.ClientLibraries = function () {}; 759 760 /** 761 * Enum of client libraries supported for optional external include 762 */ 763 MyOpenSpace.ClientLibraries.Scripts = { 764 PROTOTYPE: "prototype", 765 JQUERY: "jquery", 766 MYSPACE_WIDGETS: "myopensocial.widgets", 767 SCRIPTACULOUS: "scriptaculous", 768 SILVERLIGHT: "silverlight", 769 MOOTOOLS: "mootools", 770 AIR: "adobeair" 771 }; 772 773 /** 774 * Dynamically include optional client libraries 775 * @param {Object} script 776 */ 777 MyOpenSpace.ClientLibraries.includeScript = function (scriptRef) { 778 var srcPath = "/OpenSocial/"; 779 var extSource = srcPath + "JSExtensions/"; 780 781 var root; 782 try{ 783 root = document.getElementsByTagName('head').item(0); 784 if(!root){ 785 root = document.getElementsByTagName("body")[0]; 786 } 787 } 788 catch(ex){ } 789 790 if(!root){ 791 throw "Malformed markup - no head or body element found"; 792 } 793 794 var src = null; 795 var libs = MyOpenSpace.ClientLibraries.Scripts; 796 797 switch(scriptRef){ 798 case libs.MYSPACE_WIDGETS: 799 src = srcPath + "MyOpenSpace002.Widgets.js"; 800 break; 801 case libs.PROTOTYPE: 802 src = extSource + "prototype/prototype.js"; 803 break; 804 case libs.JQUERY: 805 src = extSource + "jquery/jquery-1.2.3.min.js"; 806 break; 807 case libs.SCRIPTACULOUS: 808 src = extSource + "scriptaculous/scriptaculous-full-1.8.1.js"; 809 break; 810 case libs.SILVERLIGHT: 811 src = extSource + "silverlight/Silverlight.js"; 812 break; 813 case libs.MOOTOOLS: 814 src = extSource + "mootools/mootools-release-1.11.js"; 815 break; 816 case libs.AIR: 817 src = extSource + "air/AIRAliases.js"; 818 break; 819 } 820 821 if(!src){ 822 throw "Source script not found in supported list"; 823 } 824 825 var scriptTag = document.createElement('script'); 826 scriptTag.setAttribute('language', 'javascript'); 827 scriptTag.setAttribute('type', 'text/javascript'); 828 scriptTag.setAttribute('src', src); 829 root.appendChild(scriptTag); 830 };/** 831 * Copyright 2007 Fox Interactive Media 832 * <DISCLAIMER HERE> 833 * @fileoverview Interface for container and associated classes; everything needed to query/update MySpace API data via OpenSocial interface. 834 * 835 * @author mnewbould [_at_] myspace [_dot_] com (Max Newbould) 836 * @author crussell [_at_] myspace [_dot_] com (Chad Russell) 837 * @author jreyes [_at_] myspace [_dot_] com (Jorge Reyes) 838 */ 839 840 /** 841 * Maps JSON responses from the API into the various objects 842 * @class 843 * @constructor 844 * @name MyOpenSpace.DataMapper_ 845 * @private 846 */ 847 MyOpenSpace.DataMapper_ = function() { 848 this.mapData[MyOpenSpace.RequestType.FETCH_PEOPLE_FRIENDSHIP] = this.mapPeopleFriendship_; 849 this.mapData[MyOpenSpace.RequestType.FETCH_PERSON_FRIENDSHIP] = this.mapPersonFriendship_; 850 this.mapData[MyOpenSpace.RequestType.FETCH_PERSON] = this.mapPerson_; 851 this.mapData[MyOpenSpace.RequestType.FETCH_INDICATORS] = this.mapIndicators_; 852 this.mapData[MyOpenSpace.RequestType.FETCH_PERSON_STATUS] = this.mapPersonStatus_; 853 this.mapData[MyOpenSpace.RequestType.FETCH_PERSON_MOOD] = this.mapPersonMood_; 854 this.mapData[MyOpenSpace.RequestType.FETCH_PEOPLE] = this.mapPeople_; 855 this.mapData[MyOpenSpace.RequestType.FETCH_ALBUMS] = this.mapAlbums_; 856 this.mapData[MyOpenSpace.RequestType.FETCH_ALBUM] = this.mapAlbum_; 857 this.mapData[MyOpenSpace.RequestType.FETCH_VIDEOS] = this.mapVideos_; 858 this.mapData[MyOpenSpace.RequestType.FETCH_VIDEO] = this.mapVideo_; 859 this.mapData[MyOpenSpace.RequestType.FETCH_PHOTOS] = this.mapPhotos_; 860 this.mapData[MyOpenSpace.RequestType.FETCH_PHOTO] = this.mapPhoto_; 861 this.mapData[MyOpenSpace.RequestType.FETCH_PERSON_DATA] = this.mapPersonAppData_; 862 this.mapData[MyOpenSpace.RequestType.FETCH_ACTIVITIES] = this.mapActivities_; 863 this.mapData['mapSimplePersonData_'] = this.mapSimplePersonData_; 864 this.mapData['mapPersonData_'] = this.mapPersonData_; 865 }; 866 867 868 MyOpenSpace.DataMapper_.prototype = { 869 /** 870 * Object that contains the mapping of MyOpenSpace.RequestType Enum element to the function that will 871 * map the server response data. 872 * @memberOf MyOpenSpace.DataMapper_ 873 * @private 874 * @private 875 */ 876 mapData: {}, 877 /** 878 * Maps a server response into a opensocial.Collection of MyOpenSpace.Photo objects 879 * @function 880 * @return {opensocial.Collection} 881 * @param {XMLHttpRequest} obj The response from the server 882 * @memberOf MyOpenSpace.DataMapper_ 883 * @private 884 */ 885 mapPhotos_: function(obj) { 886 try { 887 var unmapped = gadgets.json.parse(obj.responseText); 888 } 889 catch (err) { 890 return null; 891 } 892 var photos = []; 893 var photo; 894 var ns = MyOpenSpace.Photo.Field; 895 896 if (unmapped.photos) { 897 for (var i = 0; i < unmapped.photos.length; i++) { 898 photo = new opensocial.Container.get().newPhoto(); 899 photo.setField_(ns.PHOTO_ID, unmapped.photos[i].id); 900 photo.setField_(ns.PHOTO_URI, unmapped.photos[i].photoUri); 901 photo.setField_(ns.IMAGE_URI, unmapped.photos[i].imageUri); 902 photo.setField_(ns.CAPTION, unmapped.photos[i].caption); 903 //photo.setField_(ns.COMMENTS_COUNT,unmapped.photos[i].commentsCount); 904 photos.push(photo); 905 } 906 } 907 908 return opensocial.Container.get().newCollection(photos, 0, unmapped.count); 909 }, 910 911 /** 912 * Maps a server response into a MyOpenSpace.Photo object 913 * @function 914 * @return {MyOpenSpace.Photo} 915 * @param {XMLHttpRequest} obj The response from the server 916 * @private 917 */ 918 mapPhoto_: function(obj) { 919 try { 920 var unmapped = gadgets.json.parse(obj.responseText); 921 } 922 catch (err) { 923 return null; 924 } 925 var photo = new opensocial.Container.get().newPhoto(); 926 var ns = MyOpenSpace.Photo.Field; 927 928 if (unmapped) { 929 photo.setField_(ns.PHOTO_ID, unmapped.id); 930 photo.setField_(ns.PHOTO_URI, unmapped.photoUri); 931 photo.setField_(ns.IMAGE_URI, unmapped.imageUri); 932 photo.setField_(ns.CAPTION, unmapped.caption); 933 //photo.setField_(ns.COMMENTS_COUNT,unmapped.commentsCount); 934 } 935 936 return photo; 937 }, 938 /** 939 * Maps a server response into a valid JSON Object. 940 * @function 941 * @return {Object} 942 * @param {XMLHttpRequest} obj The response from the server 943 * @param {opensocial.EscapeType}encoding Enum value to determine if the results will be html escape or not 944 * @private 945 */ 946 mapPersonAppData_: function(obj, encoding) { 947 var appDataXML = obj.responseXML; 948 949 if (null === appDataXML || "undefined" === typeof (appDataXML)) return null; 950 951 var userCount = appDataXML.childNodes.length; 952 var userNode = appDataXML.firstChild; 953 var userId; 954 var appDataNode; 955 var appDataCount = 0; 956 for (var i = 0; i < userNode.childNodes.length; i++) { 957 if ("userid" === userNode.childNodes[i].nodeName) 958 userId = userNode.childNodes[i].firstChild.nodeValue; 959 if ("appdata" === userNode.childNodes[i].nodeName) 960 appDataNode = userNode.childNodes[i]; 961 if ("appdatafriends" === userNode.childNodes[i].nodeName) 962 appDataNode = userNode.childNodes[i]; 963 } 964 i = 0; 965 var personAppData = {}; 966 967 if ("appdatafriends" === appDataNode.nodeName) { 968 var friendId = 0; 969 var friendNode; 970 var friendAppDataNode; 971 for (var k = 0; k < appDataNode.childNodes.length; k++) { 972 friendNode = appDataNode.childNodes[k]; 973 for (var m = 0; m < friendNode.childNodes.length; m++) { 974 if ("friendid" === friendNode.childNodes[m].nodeName) { 975 friendId = friendNode.childNodes[m].firstChild.nodeValue; 976 } 977 if ("appdata" === friendNode.childNodes[m].nodeName) { 978 friendAppDataNode = friendNode.childNodes[m]; 979 } 980 } 981 personAppData[friendId] = {}; 982 appDataCount = friendAppDataNode.getAttribute("count"); 983 for (var j = 0; j < friendAppDataNode.childNodes.length; j++) { 984 personAppData[friendId][friendAppDataNode.childNodes[j].getAttribute("name")] = friendAppDataNode.childNodes[j].getAttribute("value"); 985 } 986 } 987 } else { 988 personAppData[userId] = {}; 989 appDataCount = appDataNode.getAttribute("count"); 990 for (var i = 0; i < appDataNode.childNodes.length; i++) { 991 if ("key" === appDataNode.childNodes[i].nodeName) { 992 var dataKey = appDataNode.childNodes[i].getAttribute("name"); 993 var dataValue = gadgets.json.parse(appDataNode.childNodes[i].getAttribute("value")); 994 if (encoding !== opensocial.EscapeType.NONE){ 995 dataValue = gadgets.util.escape(dataValue); 996 } 997 personAppData[userId][dataKey] = dataValue; 998 } 999 } 1000 } 1001 return personAppData; 1002 }, 1003 /** 1004 * Maps a server response into a opensocial.Collection of MyOpenSpace.Album objects 1005 * @function 1006 * @return {opensocial.Collection} 1007 * @param {XMLHttpRequest} obj The response from the server 1008 * @private 1009 */ 1010 mapAlbums_: function(obj) { 1011 try { 1012 var unmapped = gadgets.json.parse(obj.responseText); 1013 } 1014 catch (err) { 1015 return null; 1016 } 1017 var albums = []; 1018 var album; 1019 var ns = MyOpenSpace.Album.Field; 1020 1021 if (unmapped.albums) { 1022 for (var i = 0; i < unmapped.albums.length; i++) { 1023 album = new opensocial.Container.get().newAlbum(); 1024 album.setField_(ns.ALBUM_ID, unmapped.albums[i].id); 1025 album.setField_(ns.ALBUM_URI, unmapped.albums[i].albumUri); 1026 album.setField_(ns.TITLE, unmapped.albums[i].title); 1027 album.setField_(ns.LOCATION, unmapped.albums[i].location); 1028 album.setField_(ns.DEFAULT_IMAGE, unmapped.albums[i].defaultImage); 1029 album.setField_(ns.PRIVACY, unmapped.albums[i].privacy); 1030 album.setField_(ns.PHOTO_COUNT, unmapped.albums[i].photoCount); 1031 album.setField_(ns.PHOTOS_URI, unmapped.albums[i].photosUri); 1032 albums.push(album); 1033 } 1034 } 1035 1036 return opensocial.Container.get().newCollection(albums, 0, unmapped.count); 1037 }, 1038 1039 /** 1040 * Maps a server response into a MyOpenSpace.Indicator object 1041 * @function 1042 * @return {MyOpenSpace.Indicators} 1043 * @param {XMLHttpRequest} obj The response from the server 1044 * @private 1045 */ 1046 mapIndicators_: function(obj) { 1047 try { 1048 var unmapped = gadgets.json.parse(obj.responseText); 1049 } 1050 catch (err) { 1051 return null; 1052 } 1053 var indicators = new opensocial.Container.get().newIndicators(); 1054 var ns = MyOpenSpace.Indicators.Field; 1055 1056 if (unmapped) { 1057 indicators.setField_(ns.MAIL, unmapped.mailurl ? true : false); 1058 indicators.setField_(ns.MAIL_URL, unmapped.mailurl); 1059 1060 indicators.setField_(ns.BIRTHDAY, unmapped.birthdayurl ? true : false); 1061 indicators.setField_(ns.BIRTHDAY_URL, unmapped.birthdayurl); 1062 1063 indicators.setField_(ns.BLOG_COMMENT, unmapped.blogcommenturl ? true : false); 1064 indicators.setField_(ns.BLOG_COMMENT_URL, unmapped.blogcommenturl); 1065 1066 indicators.setField_(ns.BLOG_SUBSCRIPTION_POST, unmapped.blogsubscriptionposturl ? true : false); 1067 indicators.setField_(ns.BLOG_SUBSCRIPTION_POST_URL, unmapped.blogsubscriptionposturl); 1068 1069 indicators.setField_(ns.COMMENT, unmapped.commenturl ? true : false); 1070 indicators.setField_(ns.COMMENT_URL, unmapped.commenturl); 1071 1072 indicators.setField_(ns.EVENT_INVITATION, unmapped.eventinvitationurl ? true : false); 1073 indicators.setField_(ns.EVENT_INVITATION_URL, unmapped.eventinvitationurl); 1074 1075 indicators.setField_(ns.FRIEND_REQUEST, unmapped.friendsrequesturl ? true : false); 1076 indicators.setField_(ns.FRIEND_REQUEST_URL, unmapped.friendsrequesturl); 1077 1078 indicators.setField_(ns.GROUP_NOTIFICATION, unmapped.groupnotificationurl ? true : false); 1079 indicators.setField_(ns.GROUP_NOTIFICATION_URL, unmapped.groupnotificationurl); 1080 1081 indicators.setField_(ns.PHOTO_TAG_APPROVAL, unmapped.phototagapprovalurl ? true : false); 1082 indicators.setField_(ns.PHOTO_TAG_APPROVAL_URL, unmapped.phototagapprovalurl); 1083 1084 indicators.setField_(ns.PICTURE_COMMENT, unmapped.picturecommenturl ? true : false); 1085 indicators.setField_(ns.PICTURE_COMMENT_URL, unmapped.picturecommenturl); 1086 1087 indicators.setField_(ns.RECENTLY_ADDED_FRIEND, unmapped.recentlyaddedfriendurl ? true : false); 1088 indicators.setField_(ns.RECENTLY_ADDED_FRIEND_URL, unmapped.recentlyaddedfriendurl); 1089 1090 indicators.setField_(ns.VIDEO_COMMENT, unmapped.videocommenturl ? true : false); 1091 indicators.setField_(ns.VIDEO_COMMENT_URL, unmapped.videocommenturl); 1092 1093 indicators.setField_(ns.VIDEO_PROCESS, unmapped.videoprocessurl ? true : false); 1094 indicators.setField_(ns.VIDEO_PROCESS_URL, unmapped.videoprocessurl); 1095 1096 } 1097 1098 return indicators; 1099 }, 1100 1101 /** 1102 * Maps a server response into a MyOpenSpace.PersonStatus object 1103 * @function 1104 * @return {MyOpenSpace.PersonStatus} 1105 * @param {XMLHttpRequest} obj The response from the server 1106 * @private 1107 */ 1108 mapPersonStatus_: function(obj) { 1109 try { 1110 var unmapped = gadgets.json.parse(obj.responseText); 1111 } 1112 catch (err) { 1113 return null; 1114 } 1115 var personStatus = new opensocial.Container.get().newPersonStatus(); 1116 var ns = MyOpenSpace.PersonStatus.Field; 1117 1118 if (unmapped) { 1119 personStatus.setField_(ns.STATUS, unmapped.status); 1120 } 1121 1122 return personStatus; 1123 }, 1124 1125 /** 1126 * Maps a server response into a MyOpenSpace.PersonMood object 1127 * @function 1128 * @return {MyOpenSpace.PersonMood} 1129 * @param {XMLHttpRequest} obj The response from the server 1130 * @private 1131 */ 1132 mapPersonMood_: function(obj) { 1133 try { 1134 var unmapped = gadgets.json.parse(obj.responseText); 1135 } 1136 catch (err) { 1137 return null; 1138 } 1139 var personMood = new opensocial.Container.get().newPersonMood(); 1140 var ns = MyOpenSpace.PersonMood.Field; 1141 1142 if (unmapped) { 1143 personMood.setField_(ns.MOOD, unmapped.mood); 1144 personMood.setField_(ns.MOOD_IMAGE_URL, unmapped.moodImageUrl); 1145 personMood.setField_(ns.MOOD_LAST_UPDATED, unmapped.moodLastUpdated); 1146 } 1147 1148 return personMood; 1149 }, 1150 1151 /** 1152 * Maps a server response into a MyOpenSpace.Album object 1153 * @function 1154 * @return {MyOpenSpace.Album} 1155 * @param {XMLHttpRequest} obj The response from the server 1156 * @private 1157 */ 1158 mapAlbum_: function(obj) { 1159 try { 1160 var unmapped = gadgets.json.parse(obj.responseText); 1161 } 1162 catch (err) { 1163 return null; 1164 } 1165 var album = new opensocial.Container.get().newAlbum(); 1166 var ns = MyOpenSpace.Album.Field; 1167 1168 if (unmapped) { 1169 album.setField_(ns.ALBUM_ID, unmapped.id); 1170 album.setField_(ns.ALBUM_URI, unmapped.albumUri); 1171 album.setField_(ns.TITLE, unmapped.title); 1172 album.setField_(ns.LOCATION, unmapped.location); 1173 album.setField_(ns.DEFAULT_IMAGE, unmapped.defaultImage); 1174 album.setField_(ns.PRIVACY, unmapped.privacy); 1175 album.setField_(ns.PHOTO_COUNT, unmapped.photoCount); 1176 album.setField_(ns.PHOTOS_URI, unmapped.photosUri); 1177 } 1178 1179 return album; 1180 }, 1181 1182 /** 1183 * Maps a server response into a opensocial.Collection of MyOpenSpace.Friendship objects 1184 * @function 1185 * @return {opensocial.Collection} 1186 * @param {XMLHttpRequest} obj The response from the server 1187 * @private 1188 */ 1189 mapPersonFriendship_: function(obj) { 1190 var unmapped; 1191 try { 1192 unmapped = gadgets.json.parse(obj.responseText); 1193 } 1194 catch (err) { 1195 return null; 1196 } 1197 var friendship = new opensocial.Container.get().newFriendship(); 1198 var ns = MyOpenSpace.Friendship.Field; 1199 1200 if (unmapped.friendship) { 1201 1202 friendship.setField_(ns.IS_FRIEND, unmapped.friendship[0].areFriends); 1203 friendship.setField_(ns.FRIEND_ID, unmapped.friendship[0].friendId); 1204 1205 } 1206 1207 return friendship; 1208 }, 1209 1210 /** 1211 * Maps a server response into a opensocial.Collection of MyOpenSpace.Friendship objects 1212 * @function 1213 * @return {opensocial.Collection} 1214 * @param {XMLHttpRequest} obj The response from the server 1215 * @private 1216 */ 1217 mapPeopleFriendship_: function(obj) { 1218 try { 1219 var unmapped = gadgets.json.parse(obj.responseText); 1220 } 1221 catch (err) { 1222 return null; 1223 } 1224 var friendships = []; 1225 var ns = MyOpenSpace.Friendship.Field; 1226 1227 if (unmapped.friendship) { 1228 for (var i = 0; i < unmapped.friendship.length; i++) { 1229 var friendship = new opensocial.Container.get().newFriendship(); 1230 friendship.setField_(ns.IS_FRIEND, unmapped.friendship[i].areFriends); 1231 friendship.setField_(ns.FRIEND_ID, unmapped.friendship[i].friendId); 1232 friendships.push(friendship); 1233 } 1234 } 1235 1236 return opensocial.Container.get().newCollection(friendships, 0, friendships.length); 1237 }, 1238 1239 1240 /** 1241 * Maps a server response into a opensocial.Collection of MyOpenSpace.Video objects 1242 * @function 1243 * @return {opensocial.Collection} 1244 * @param {XMLHttpRequest} obj The response from the server 1245 * @private 1246 */ 1247 mapVideos_: function(obj) { 1248 try { 1249 var unmapped = gadgets.json.parse(obj.responseText); 1250 } 1251 catch (err) { 1252 return null; 1253 } 1254 var videos = []; 1255 var video; 1256 var ns = MyOpenSpace.Video.Field; 1257 1258 if (unmapped.videos) { 1259 for (var i = 0; i < unmapped.videos.length; i++) { 1260 video = new opensocial.Container.get().newVideo(); 1261 video.setField_(ns.VIDEO_ID, unmapped.videos[i].id); 1262 video.setField_(ns.VIDEO_URI, unmapped.videos[i].videoUri); 1263 video.setField_(ns.TITLE, unmapped.videos[i].title); 1264 video.setField_(ns.DATE_CREATED, unmapped.videos[i].datecreated); 1265 video.setField_(ns.LAST_UPDATE, unmapped.videos[i].dateupdated); 1266 video.setField_(ns.MEDIA_TYPE, unmapped.videos[i].mediatype); 1267 video.setField_(ns.THUMB_URI, unmapped.videos[i].thumbnail); 1268 video.setField_(ns.DESCRIPTION, unmapped.videos[i].description); 1269 video.setField_(ns.MEDIA_STATUS, unmapped.videos[i].mediastatus); 1270 video.setField_(ns.RUN_TIME, unmapped.videos[i].runtime); 1271 video.setField_(ns.TOTAL_VIEWS, unmapped.videos[i].totalviews); 1272 video.setField_(ns.TOTAL_COMMENTS, unmapped.videos[i].totalcomments); 1273 video.setField_(ns.TOTAL_RATING, unmapped.videos[i].totalrating); 1274 video.setField_(ns.TOTAL_VOTES, unmapped.videos[i].totalvotes); 1275 video.setField_(ns.COUNTRY, unmapped.videos[i].country); 1276 video.setField_(ns.LANGUAGE, unmapped.videos[i].language); 1277 videos.push(video); 1278 } 1279 } 1280 1281 return opensocial.Container.get().newCollection(videos, 0, unmapped.count); 1282 }, 1283 1284 /** 1285 * Maps a server response into a MyOpenSpace.Video object 1286 * @function 1287 * @return {MyOpenSpace.Video} 1288 * @param {XMLHttpRequest} obj The response from the server 1289 * @private 1290 * @private 1291 */ 1292 mapVideo_: function(obj) { 1293 try { 1294 var unmapped = gadgets.json.parse(obj.responseText); 1295 } 1296 catch (err) { 1297 return null; 1298 } 1299 var video = new opensocial.Container.get().newVideo(); 1300 var ns = MyOpenSpace.Video.Field; 1301 1302 if (unmapped) { 1303 video.setField_(ns.VIDEO_ID, unmapped.id); 1304 video.setField_(ns.VIDEO_URI, unmapped.videoUri); 1305 video.setField_(ns.TITLE, unmapped.title); 1306 video.setField_(ns.DATE_CREATED, unmapped.datecreated); 1307 video.setField_(ns.LAST_UPDATE, unmapped.dateupdated); 1308 video.setField_(ns.MEDIA_TYPE, unmapped.mediatype); 1309 video.setField_(ns.THUMB_URI, unmapped.thumbnail); 1310 video.setField_(ns.DESCRIPTION, unmapped.description); 1311 video.setField_(ns.MEDIA_STATUS, unmapped.mediastatus); 1312 video.setField_(ns.RUN_TIME, unmapped.runtime); 1313 video.setField_(ns.TOTAL_VIEWS, unmapped.totalviews); 1314 video.setField_(ns.TOTAL_COMMENTS, unmapped.totalcomments); 1315 video.setField_(ns.TOTAL_RATING, unmapped.totalrating); 1316 video.setField_(ns.TOTAL_VOTES, unmapped.totalvotes); 1317 video.setField_(ns.COUNTRY, unmapped.country); 1318 video.setField_(ns.LANGUAGE, unmapped.language); 1319 } 1320 1321 return video; 1322 }, 1323 1324 /** 1325 * Maps a server response into a opensocial.Collection of MyOpenSpace.Person objects 1326 * @function 1327 * @return {opensocial.Collection} 1328 * @param {XMLHttpRequest} obj The response from the server 1329 * @private 1330 * @private 1331 */ 1332 mapPeople_: function(obj) { 1333 try { 1334 var unmapped = gadgets.json.parse(obj.responseText); 1335 } 1336 catch (err) { 1337 return null; 1338 } 1339 var friends = []; 1340 var person; 1341 var unmappedData; 1342 1343 1344 if (typeof(unmapped.users) !== 'undefined'){ 1345 unmappedData = []; 1346 for (var j in unmapped.users){ 1347 unmappedData[j] ={ 1348 "id": "myspace.com:" + unmapped.users[j].userId, 1349 "nickname" : unmapped.users[j].name, 1350 "thumbnailUrl" : unmapped.users[j].image, 1351 "profileUrl" : unmapped.users[j].webUri 1352 }; 1353 } 1354 } 1355 else if (typeof(unmapped.entry) === 'undefined'){ 1356 return opensocial.Container.get().newCollection([], 0, 0); 1357 } 1358 else if (unmapped.entry.constructor == Array){ 1359 unmappedData = unmapped.entry; 1360 } 1361 else{ 1362 unmappedData = [unmapped.entry]; 1363 } 1364 1365 var person; 1366 var friends = []; 1367 for (var i in unmappedData){ 1368 person = this.mapSimplePersonData_(unmappedData[i]); 1369 friends[i] = person; 1370 } 1371 return opensocial.Container.get().newCollection(friends, 0, unmapped.count); 1372 }, 1373 /** 1374 * Maps server response data object to a MyOpenSpace.Person object filling ID, Thumbnail, 1375 * nickname, profileUrl and name fiedls 1376 * @function 1377 * @return {MyOpenSpace.Person} 1378 * @param {Object} unmappedData The response person object from the server 1379 * @private 1380 */ 1381 mapSimplePersonData_:function(unmappedData){ 1382 var isOwner = false; 1383 var isViewer = false; 1384 if (typeof(unmappedData.id) !== 'undefined'){ 1385 var id = unmappedData.id.split(":")[1]; 1386 var viewerId = gadgets.views.getParams().viewerId; 1387 var ownerId = gadgets.views.getParams().ownerId; 1388 isOwner = (id === ownerId); 1389 isViewer = (id === viewerId); 1390 } 1391 1392 var person = new opensocial.Container.get().newPerson(null, isOwner, isViewer); 1393 var ns = opensocial.Person.Field; 1394 /** 1395 * Generic method Populates person field specify by personField if obj is different from undefined. 1396 * @param {Object} personField Field to map. 1397 * @param {Object} obj Data to map 1398 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1399 * @private 1400 */ 1401 var mapGeneric = function(personField, obj, explicitPerson){ 1402 if (typeof(obj) === 'undefined') return; 1403 var personObject = person || explicitPerson; 1404 personObject.setField_(personField, obj); 1405 }; 1406 /** 1407 * Populates person HAS_APP field if hasApp parameter is present. 1408 * @param {Object} hasApp Value to map. 1409 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1410 * @private 1411 */ 1412 var mapHasApp = function(hasApp, explicitPerson){ 1413 if (typeof(hasApp) === 'undefined') return; 1414 var personObject = person || explicitPerson; 1415 var hasAppObj = (('' + hasApp).toLowerCase() === 'true'); 1416 personObject.setField_(ns.HAS_APP, hasAppObj); 1417 }; 1418 /** 1419 * Populates person Name field with the information provided in name, familyName, givenName. 1420 * @param {Object} name Display name 1421 * @param {Object} familyName Family name 1422 * @param {Object} givenName Given Name 1423 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1424 * @private 1425 */ 1426 var mapName = function(name, familyName, givenName, explicitPerson) { 1427 if (typeof(name) === 'undefined' && typeof(familyName) === 'undefined' && typeof(givenName) === 'undefined') return; 1428 var personObject = person || explicitPerson; 1429 var nameParams = {}; 1430 if (typeof(name) !== 'undefined') nameParams[opensocial.Name.Field.UNSTRUCTURED] = name; 1431 if (typeof(givenName) !== 'undefined') nameParams[opensocial.Name.Field.GIVEN_NAME] = givenName; 1432 if (typeof(familyName) !== 'undefined') nameParams[opensocial.Name.Field.FAMILY_NAME] = familyName; 1433 var personName = new opensocial.Name(nameParams); 1434 personObject.setField_(ns.NAME, personName); 1435 }; 1436 1437 mapGeneric(ns.ID, unmappedData.id); 1438 mapGeneric(ns.THUMBNAIL_URL, unmappedData.thumbnailUrl); 1439 mapGeneric(ns.NICKNAME, unmappedData.nickname); 1440 mapGeneric(ns.PROFILE_URL, unmappedData.profileUrl); 1441 mapName(unmappedData.displayName, unmappedData.familyName, unmappedData.givenName); 1442 mapHasApp(unmappedData.hasApp); 1443 1444 return person; 1445 }, 1446 /** 1447 * Maps a server response data object to a MyOpenSpace.Person object 1448 * @function 1449 * @return {MyOpenSpace.Person} 1450 * @param {Object} The response person object from the server 1451 * @private 1452 */ 1453 mapPersonData_:function(unmappedData){ 1454 1455 var person = this.mapSimplePersonData_(unmappedData); 1456 var ns = opensocial.Person.Field; 1457 var mns = MyOpenSpace.Person.Field; 1458 /** 1459 * Generic method Populates person field specify by personField if obj is different from undefined. 1460 * @param {Object} personField Field to map. 1461 * @param {Object} obj data to map 1462 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1463 * @private 1464 */ 1465 var mapGeneric = function(personField, obj, explicitPerson){ 1466 if (typeof(obj) === 'undefined') return; 1467 var personObject = person || explicitPerson; 1468 personObject.setField_(personField, obj); 1469 }; 1470 /** 1471 * Populates BODY_TYPE person field if bodyType is different from undefined. 1472 * @param {Object} bodyType Body type value. 1473 * @param {Object} explicitPerson pPerson object to use. If undefined the default person object will be used. 1474 * @private 1475 */ 1476 var mapBodyType = function(bodyType, explicitPerson){ 1477 if (typeof(bodyType) === 'undefined') return; 1478 var personObject = person || explicitPerson; 1479 var bodyTypeParams = {}; 1480 bodyTypeParams[opensocial.BodyType.Field.BUILD] = bodyType.build; 1481 bodyTypeParams[opensocial.BodyType.Field.HEIGHT] = bodyType.height; 1482 var bodyTypeObj = new opensocial.BodyType(bodyTypeParams); 1483 personObject.setField_(ns.BODY_TYPE, bodyTypeObj); 1484 }; 1485 /** 1486 * Populates CURRENT_LOCATION person field if currentLocation is different from undefined. 1487 * @param {Object} currentLocation Current location value. 1488 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1489 * @private 1490 */ 1491 var mapCurrentLocation = function(currentLocation, explicitPerson){ 1492 if (typeof(currentLocation) === 'undefined') return; 1493 var personObject = person || explicitPerson; 1494 var addressParams = {}; 1495 addressParams[opensocial.Address.Field.REGION] = currentLocation.region; 1496 addressParams[opensocial.Address.Field.POSTAL_CODE] = currentLocation.postalCode; 1497 addressParams[opensocial.Address.Field.COUNTRY] = currentLocation.country; 1498 var currentLocationObj = new opensocial.Address(addressParams); 1499 personObject.setField_(ns.CURRENT_LOCATION, currentLocationObj); 1500 }; 1501 /** 1502 * Populates DATE_OF_BIRTH person field if dateOfBirth is different from undefined. 1503 * The date should be formatted yyyy-MM-ddTHH:mm:ss-00:00:00 1504 * @param {Object} dateOfBirth Formated date of birth value. 1505 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1506 * @private 1507 */ 1508 var mapDateOfBirth = function(dateOfBirth, explicitPerson){ 1509 if (typeof(dateOfBirth) === 'undefined') return; 1510 var personObject = person || explicitPerson; 1511 var dateOfBirthObj = new Date(); 1512 dateOfBirthObj.setDate(dateOfBirth.substr(8,2)); 1513 dateOfBirthObj.setMonth(dateOfBirth.substr(5,2)); 1514 dateOfBirthObj.setFullYear(dateOfBirth.substr(0,4)); 1515 dateOfBirthObj.setHours(0); 1516 dateOfBirthObj.setMinutes(0); 1517 dateOfBirthObj.setSeconds(0); 1518 dateOfBirthObj.setMilliseconds(0); 1519 personObject.setField_(ns.DATE_OF_BIRTH, dateOfBirthObj); 1520 }; 1521 /** 1522 * Populates DRINKER person field if drinker is different from undefined. 1523 * @param {Object} drinker Drinker value object. 1524 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1525 * @private 1526 */ 1527 var mapDrinker = function(drinker, explicitPerson){ 1528 if (typeof(drinker) === 'undefined') return; 1529 if (typeof(drinker.key) === 'undefined' && drinker.value === 'undefined') return; 1530 var personObject = person || explicitPerson; 1531 var drinkerKey = null; 1532 var drinkerValue = drinker.value; 1533 if (drinker.key !== null && typeof(drinker.key) !== 'undefined') { 1534 if (drinker.key.toLowerCase() === 'yes') drinkerKey = opensocial.Enum.Drinker.YES; 1535 else if (drinker.key.toLowerCase() === 'no') drinkerKey = opensocial.Enum.Drinker.NO; 1536 else if (drinker.key.toLowerCase() === 'heavily') drinkerKey = opensocial.Enum.Drinker.HEAVILY; 1537 else if (drinker.key.toLowerCase() === 'occasionally') drinkerKey = opensocial.Enum.Drinker.OCCASIONALLY; 1538 else if (drinker.key.toLowerCase() === 'quit') drinkerKey = opensocial.Enum.Drinker.QUIT; 1539 else if (drinker.key.toLowerCase() === 'quitting') drinkerKey = opensocial.Enum.Drinker.QUITTING; 1540 else if (drinker.key.toLowerCase() === 'regularly') drinkerKey = opensocial.Enum.Drinker.REGULARLY; 1541 else if (drinker.key.toLowerCase() === 'socially') drinkerKey = opensocial.Enum.Drinker.SOCIALLY; 1542 }; 1543 personObject.setField_(ns.DRINKER, new opensocial.Enum(drinkerKey, drinkerValue)); 1544 }; 1545 /** 1546 * Populates GENDER person field if gender is different from undefined. 1547 * @param {Object} gender Gender value object 1548 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1549 * @private 1550 */ 1551 var mapGender = function(gender, explicitPerson) { 1552 if (typeof(gender) === 'undefined') return; 1553 var personObject = person || explicitPerson; 1554 var genderObj; 1555 if (gender.toLowerCase() === "male") genderObj = opensocial.Enum.Gender.MALE; 1556 else if (gender.toLowerCase() === "female") genderObj = opensocial.Enum.Gender.FEMALE; 1557 if (typeof(genderObj) !== 'undefined') 1558 personObject.setField_(ns.GENDER, new opensocial.Enum(genderObj, genderObj)); 1559 }; 1560 /** 1561 * Populates JOBS person field if jobs is different from undefined. 1562 * @param {Object} jobs Array of jobs objects to map. 1563 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1564 * @private 1565 */ 1566 var mapJobs = function(jobs, explicitPerson){ 1567 if (typeof(jobs) === 'undefined') return; 1568 var personObject = person || explicitPerson; 1569 var jobsObj = []; 1570 for (var i in jobs){ 1571 var organizationParams = {}; 1572 organizationParams[opensocial.Organization.Field.NAME] = jobs[i].name; 1573 organizationParams[opensocial.Organization.Field.TITLE] = jobs[i].title; 1574 jobsObj[i] = new opensocial.Organization(organizationParams); 1575 } 1576 personObject.setField_(ns.JOBS, jobsObj); 1577 }; 1578 /** 1579 * Populates NETWORK_PRESENCE person field if networkPresence is different from undefined. 1580 * @param {Object} networkPresence Network presence value object 1581 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1582 * @private 1583 */ 1584 var mapNetworkPresence = function(networkPresence, explicitPerson){ 1585 if (typeof(networkPresence) === 'undefined') return; 1586 if (typeof(networkPresence.key) === 'undefined' && typeof(networkPresence.value) === 'undefined') return; 1587 var personObject = person || explicitPerson; 1588 var networkPresenceKey = null; 1589 var networkValue = networkPresence.value; 1590 if (networkPresence.key != null && typeof(networkPresence.key) !== 'undefined' ) { 1591 if (networkPresence.key.toLowerCase() === 'offline') networkPresenceKey = opensocial.Enum.Presence.OFFLINE; 1592 else if (networkPresence.key.toLowerCase() === 'online') networkPresenceKey = opensocial.Enum.Presence.ONLINE; 1593 else if (networkPresence.key.toLowerCase() === 'away') networkPresenceKey = opensocial.Enum.Presence.AWAY; 1594 else if (networkPresence.key.toLowerCase() === 'chat') networkPresenceKey = opensocial.Enum.Presence.CHAT; 1595 else if (networkPresence.key.toLowerCase() === 'dnd') networkPresenceKey = opensocial.Enum.Presence.DND; 1596 else if (networkPresence.key.toLowerCase() === 'xa') networkPresenceKey = opensocial.Enum.Presence.XA; 1597 } 1598 personObject.setField_(ns.NETWORK_PRESENCE, new opensocial.Enum(networkPresenceKey, networkValue)); 1599 }; 1600 /** 1601 * Populates PROFILE_SONG person field if profileSong is different from undefined. 1602 * @param {Object} profileSong Profile song value. 1603 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1604 * @private 1605 */ 1606 var mapProfileSong = function(profileSong, explicitPerson){ 1607 if (typeof(profileSong) === 'undefined') return; 1608 var personObject = person || explicitPerson; 1609 var urlParams = {}; 1610 urlParams[opensocial.Url.Field.LINK_TEXT] = profileSong; 1611 var urlObj = new opensocial.Url(urlParams); 1612 personObject.setField_(ns.PROFILE_SONG, urlObj); 1613 }; 1614 /** 1615 * Populates LOOKING_FOR person field if lookingFor is different from undefined. 1616 * @param {Object} lookingFor Looking for value. 1617 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1618 * @private 1619 */ 1620 var mapLookingFor = function(lookingFor, explicitPerson){ 1621 if (typeof(lookingFor) === 'undefined') return; 1622 var personObject = person || explicitPerson; 1623 personObject.setField_(ns.LOOKING_FOR, new opensocial.Enum(null, lookingFor)); 1624 }; 1625 /** 1626 * Populates SMOKER person field if smoker is different from undefined. 1627 * @param {Object} smoker smoker value object. 1628 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1629 * @private 1630 */ 1631 var mapSmoker = function(smoker, explicitPerson){ 1632 if (typeof(smoker) === 'undefined') return; 1633 if (typeof(smoker.key) === 'undefined' && somoker.value === 'undefined') return; 1634 var personObject = person || explicitPerson; 1635 var smokerKey = null; 1636 var smokerValue = smoker.value; 1637 if (smoker.key !== null && typeof(smoker.key) !== 'undefined') { 1638 if (smoker.key.toLowerCase() === 'heavily') smokerKey = opensocial.Enum.Smoker.HEAVILY; 1639 else if (smoker.key.toLowerCase() === 'no') smokerKey = opensocial.Enum.Smoker.NO; 1640 else if (smoker.key.toLowerCase() === 'occasionally') smokerKey = opensocial.Enum.Smoker.OCCASIONALLY; 1641 else if (smoker.key.toLowerCase() === 'quit') smokerKey = opensocial.Enum.Smoker.QUIT; 1642 else if (smoker.key.toLowerCase() === 'quitting') smokerKey = opensocial.Enum.Smoker.QUITTING; 1643 else if (smoker.key.toLowerCase() === 'regularly') smokerKey = opensocial.Enum.Smoker.REGULARLY; 1644 else if (smoker.key.toLowerCase() === 'socially') smokerKey = opensocial.Enum.Smoker.SOCIALLY; 1645 else if (smoker.key.toLowerCase() === 'yes') smokerKey = opensocial.Enum.Smoker.YES; 1646 } 1647 1648 personObject.setField_(ns.SMOKER, new opensocial.Enum(smokerKey, smokerValue)); 1649 }; 1650 /** 1651 * Populates URLS person field if urls is different from undefined. 1652 * @param {Object} urls Array of urls objects. 1653 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1654 * @private 1655 */ 1656 var mapUrls = function(urls, explicitPerson){ 1657 if (typeof(urls) === 'undefined') return; 1658 var personObject = person || explicitPerson; 1659 var urlsObj =[]; 1660 for (var i in urls){ 1661 var urlParams = {}; 1662 urlParams[opensocial.Url.Field.ADDRESS] = urls[i].value; 1663 urlParams[opensocial.Url.Field.TYPE] = urls[i].type; 1664 urlsObj[i] = new opensocial.Url(urlParams); 1665 } 1666 personObject.setField_(ns.URLS, urlsObj); 1667 }; 1668 /** 1669 * Populates the MySpace LARGE_IMAGE and MEDIUM_IMAGE extensions fields if photos is different from undefined. 1670 * @param {Object} photos photos value object. 1671 * @param {Object} explicitPerson Person object to use. If undefined the default person object will be used. 1672 * @private 1673 */ 1674 var mapPhotos = function(photos, explicitPerson){ 1675 if (typeof(photos) === 'undefined') return; 1676 var personObject = person || explicitPerson; 1677 var image; 1678 var urlParams; 1679 for (var i in photos){ 1680 var type = photos[i].type; 1681 var val = photos[i].value; 1682 if (type === 'medium' && typeof(val) !== 'undefined'){ 1683 urlParams = {}; 1684 urlParams[opensocial.Url.Field.ADDRESS] = val; 1685 urlParams[opensocial.Url.Field.TYPE] = 'medium image'; 1686 personObject.setField_(mns.MEDIUM_IMAGE, new opensocial.Url(urlParams)); 1687 } 1688 else if (type === 'large' && typeof(val) !== 'undefined'){ 1689 urlParams = {}; 1690 urlParams[opensocial.Url.Field.ADDRESS] = val; 1691 urlParams[opensocial.Url.Field.TYPE] = 'large image'; 1692 personObject.setField_(mns.LARGE_IMAGE, new opensocial.Url(urlParams)); 1693 } 1694 } 1695 } 1696 1697 var addressns = opensocial.Address.Field; 1698 mapGeneric(ns.ABOUT_ME, unmappedData.aboutMe); 1699 mapGeneric(ns.AGE, unmappedData.age); 1700 mapBodyType(unmappedData.bodyType); 1701 mapGeneric(ns.BOOKS, unmappedData.books); 1702 mapGeneric(ns.CHILDREN, unmappedData.children); 1703 mapCurrentLocation(unmappedData.currentLocation); 1704 mapDateOfBirth(unmappedData.dateOfBirth); 1705 mapDrinker(unmappedData.drinker); 1706 mapGeneric(ns.ETHNICITY, unmappedData.ethnicity); 1707 mapGender(unmappedData.gender); 1708 1709 mapGeneric(ns.HEROES, unmappedData.heroes); 1710 1711 mapGeneric(ns.INTERESTS, unmappedData.interests); 1712 mapJobs(unmappedData.organizations); 1713 mapGeneric(ns.MOVIES, unmappedData.movies); 1714 mapGeneric(ns.MUSIC, unmappedData.music); 1715 mapNetworkPresence(unmappedData.networkPresence); 1716 1717 mapLookingFor(unmappedData.lookingFor); 1718 mapProfileSong(unmappedData.profileSong); 1719 1720 mapGeneric(ns.RELATIONSHIP_STATUS, unmappedData.relationshipStatus); 1721 mapGeneric(ns.RELIGION, unmappedData.religion); 1722 mapGeneric(ns.SEXUAL_ORIENTATION, unmappedData.sexualOrientation); 1723 mapSmoker(unmappedData.smoker); 1724 mapGeneric(ns.STATUS, unmappedData.status); 1725 1726 mapGeneric(ns.TV_SHOWS, unmappedData.tvShows); 1727 mapUrls(unmappedData.urls); 1728 //MySpace Extensions 1729 mapPhotos(unmappedData.photos); 1730 1731 return person; 1732 }, 1733 /** 1734 * Maps a server response into a MyOpenSpace.Person object 1735 * @function 1736 * @return {MyOpenSpace.Person} 1737 * @param {XMLHttpRequest} obj The response from the server 1738 * @private 1739 */ 1740 mapPerson_: function(obj) { 1741 try { 1742 var unmapped = gadgets.json.parse(obj.responseText); 1743 } 1744 catch (err) { 1745 return null; 1746 } 1747 if (typeof (unmapped) === 'undefined') return null; 1748 if (typeof (unmapped.entry) === 'undefined' && typeof (unmapped.users) === 'undefined') return null; 1749 if (typeof (unmapped.users) !== 'undefined'){ 1750 unmappedData ={ 1751 "id": "myspace.com:" + unmapped.users[0].userId, 1752 "nickname" : unmapped.users[0].name, 1753 "thumbnailUrl" : unmapped.users[0].image, 1754 "displayName" : unmapped.users[0].name, 1755 "profileUrl" : unmapped.users[0].webUri 1756 }; 1757 } 1758 else{ 1759 unmappedData = unmapped.entry[0] || unmapped.entry; 1760 } 1761 1762 return this.mapPersonData_(unmappedData); 1763 }, 1764 1765 /** 1766 * Maps a server response into a opensocial.Collection of opensocial.Activity objects 1767 * @function 1768 * @return {opensocial.Collection} 1769 * @param {XMLHttpRequest} obj The response from the server 1770 * @private 1771 */ 1772 mapActivities_: function(obj) { 1773 if(!obj){ 1774 return null; 1775 } 1776 1777 if(obj && (!obj.responseText || obj.responseText.length < 1)){ 1778 return opensocial.Container.get().newCollection([], 0, 0); 1779 } 1780 1781 try{ 1782 var unmapped = gadgets.json.parse(obj.responseText); 1783 } 1784 catch(err){ 1785 return null; 1786 } 1787 1788 if(!unmapped){ 1789 return null; 1790 } 1791 1792 var activities = []; 1793 var activity; 1794 var ns = opensocial.Activity.Field; 1795 1796 if (unmapped.entry) { 1797 for (var i = 0; i < unmapped.entry.length; i++) { 1798 activity = new opensocial.newActivity(); 1799 activity.setField(ns.APP_ID, unmapped.entry[i].appId); 1800 activity.setField(ns.USER_ID, unmapped.entry[i].userId); 1801 activity.setField(ns.BODY, unmapped.entry[i].body); 1802 activity.setField(ns.POSTED_TIME, unmapped.entry[i].postedTime); 1803 activity.setField(ns.STREAM_FAVICON_URL, unmapped.entry[i].streamFavIconUrl); 1804 activity.setField(ns.TITLE, unmapped.entry[i].title); 1805 activity.setField(ns.TITLE_ID, unmapped.entry[i].titleId); 1806 activities.push(activity); 1807 } 1808 } 1809 return opensocial.Container.get().newCollection(activities, 0, unmapped.count); 1810 } 1811 };/** 1812 * An extension of opensocial.DataRequest, used to facilitate extended entity calls. 1813 * @class 1814 * @name MyOpenSpace.DataRequest 1815 */ 1816 //MyOpenSpace.DataRequest = function() { }; 1817 1818 /** 1819 * @constructor Creates a new DataRequest factory and execution model 1820 * @param {String} osToken OpenSocial token 1821 * @param {MyOpenSpace.EndPoint} endPoint MyOpenSpace.EndPoint object for service endpoints 1822 * @class 1823 * @name opensocial.DataRequest 1824 * @private 1825 * @internal 1826 * DataRequest is the internal MySpace implementation of an OpenSocial DataRequest 1827 */ 1828 1829 MyOpenSpace.DataRequest = function(osToken, endPoint) { 1830 //this.init.apply(this, arguments); 1831 //this.requestProcessor_ = new MyOpenSpace.RequestProcessor_(); 1832 this.osToken_ = osToken; 1833 this.endPoint_ = endPoint; 1834 1835 this.requestProcessor_ = new MyOpenSpace.RequestProcessor_(); 1836 this.requestObjects_ = new MyOpenSpace.Hash(); 1837 this.requestObjectCount_ = 0; 1838 this.busy_ = false; 1839 this.authTemplate_ = null; 1840 1841 }; 1842 1843 MyOpenSpace.DataRequest.prototype = new opensocial.DataRequest(); 1844 1845 1846 /** 1847 * Enumerates the extended filter types 1848 * @static 1849 * @class 1850 * @name MyOpenSpace.DataRequest.FilterType 1851 */ 1852 MyOpenSpace.DataRequest.FilterType = { 1853 /** 1854 * The friends that are currently online. 1855 * @memberOf MyOpenSpace.DataRequest.FilterType 1856 */ 1857 ONLINE_FRIENDS: "ONLINE_FRIENDS" 1858 }; 1859 /** 1860 * Enumerates the extended sort order types 1861 * @static 1862 * @class 1863 * @name MyOpenSpace.DataRequest.SortOrder 1864 */ 1865 MyOpenSpace.DataRequest.SortOrder = { 1866 /** 1867 * The friends that are currently online. 1868 * @memberOf MyOpenSpace.DataRequest.FilterType 1869 */ 1870 ID: "ID" 1871 }; 1872 1873 /** 1874 * Enumerates cache control mechanism for API calls 1875 * @static 1876 * @class 1877 * @name MyOpenSpace.DataRequest.CacheControl 1878 */ 1879 MyOpenSpace.DataRequest.CacheControl = { 1880 /** 1881 * Enable/disable the cache layer - boolean 1882 * @memberOf MyOpenSpace.DataRequest.CacheControl 1883 */ 1884 USE_CACHE: "USE_CACHE", 1885 /** 1886 * Specify a TTL for the item in cache - specified in seconds: 0 means no expiration 1887 * @memberOf MyOpenSpace.DataRequest.CacheControl 1888 */ 1889 REFRESH_INTERVAL: "REFRESH_INTERVAL" 1890 }; 1891 1892 /** 1893 * Enumerates the request fields used by the Photo entity 1894 * @static 1895 * @class 1896 * @name MyOpenSpace.DataRequest.PhotoRequestFields 1897 */ 1898 MyOpenSpace.DataRequest.PhotoRequestFields = { 1899 /** 1900 * Used to filter a photos request by album id, returns all photos for a particular album. 1901 * @memberOf MyOpenSpace.DataRequest.PhotoRequestFields 1902 */ 1903 ALBUM_ID: "ALBUM_ID" 1904 }; 1905 1906 /** 1907 * Creates an object to be used when sending to the server. 1908 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the photo 1909 * @param {Number} photo_id The ID of the photo to fetch 1910 * @param {undefined} opt_params Not used at this time. 1911 * @return {Object} A request object 1912 * @static 1913 * @memberOf MyOpenSpace.DataRequest 1914 */ 1915 MyOpenSpace.DataRequest.newFetchPhotoRequest = function(id, photo_id, opt_params) { 1916 return opensocial.Container.get().newFetchPhotoRequest(id, photo_id, opt_params); 1917 }; 1918 1919 /** 1920 * Creates an object to be used when sending to the server 1921 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the photos 1922 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the photos. 1923 * @return {Object} A request object 1924 * @static 1925 * @memberOf MyOpenSpace.DataRequest 1926 */ 1927 MyOpenSpace.DataRequest.newFetchPhotosRequest = function(id, photo_id, opt_params) { 1928 return opensocial.Container.get().newFetchPhotosRequest(id, photo_id, opt_params); 1929 }; 1930 1931 /** 1932 * Creates an object to be used when sending to the server 1933 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the album 1934 * @param {Number} album_id The ID of the photo to fetch 1935 * @param {undefined} opt_params Not used at this time. 1936 * @return {Object} A request object 1937 * @static 1938 * @memberOf MyOpenSpace.DataRequest 1939 */ 1940 MyOpenSpace.DataRequest.newFetchAlbumRequest = function(id, photo_id, opt_params) { 1941 return opensocial.Container.get().newFetchAlbumRequest(id, photo_id, opt_params); 1942 }; 1943 1944 /** 1945 * Creates an object to be used when sending to the server 1946 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the albums 1947 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the albums. 1948 * @return {Object} A request object 1949 * @static 1950 * @memberOf MyOpenSpace.DataRequest 1951 */ 1952 MyOpenSpace.DataRequest.newFetchAlbumsRequest = function(id, photo_id, opt_params) { 1953 return opensocial.Container.get().newFetchAlbumsRequest(id, photo_id, opt_params); 1954 }; 1955 1956 /** 1957 * Creates an object to be used when sending to the server 1958 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the album 1959 * @param {Number} video_id The ID of the photo to fetch 1960 * @param {undefined} opt_params Not used at this time. 1961 * @return {Object} A request object 1962 * @static 1963 * @memberOf MyOpenSpace.DataRequest 1964 */ 1965 MyOpenSpace.DataRequest.newFetchVideoRequest = function(id, photo_id, opt_params) { 1966 return opensocial.Container.get().newFetchVideoRequest(id, photo_id, opt_params); 1967 }; 1968 1969 /** 1970 * Creates an object to be used when sending to the server 1971 * @param {String} id The ID (VIEWER or OWNER) of the person 1972 * @param {undefined} opt_params Not used at this time. 1973 * @return {Object} A request object 1974 * @static 1975 * @memberOf MyOpenSpace.DataRequest 1976 */ 1977 MyOpenSpace.DataRequest.newFetchIndicatorsRequest = function(id, opt_params) { 1978 return opensocial.Container.get().newFetchIndicatorsRequest(id, opt_params); 1979 }; 1980 1981 /** 1982 * Creates an object to be used when sending to the server 1983 * @param {String} id The ID (VIEWER or OWNER) of the person 1984 * @param {undefined} opt_params Not used at this time. 1985 * @return {Object} A request object 1986 * @static 1987 * @memberOf MyOpenSpace.DataRequest 1988 */ 1989 MyOpenSpace.DataRequest.newFetchPersonStatusRequest = function(id, opt_params) { 1990 return opensocial.Container.get().newFetchPersonStatusRequest(id, opt_params); 1991 }; 1992 1993 /** 1994 * Creates an object to be used when sending to the server 1995 * @param {String} id The ID (VIEWER or OWNER) of the person 1996 * @param {undefined} opt_params Not used at this time. 1997 * @return {Object} A request object 1998 * @static 1999 * @memberOf MyOpenSpace.DataRequest 2000 */ 2001 MyOpenSpace.DataRequest.newFetchPersonMoodRequest = function(id, opt_params) { 2002 return opensocial.Container.get().newFetchPersonMoodRequest(id, opt_params); 2003 }; 2004 2005 /** 2006 * Creates an object to be used when sending to the server 2007 * @param {String} id The ID (VIEWER or OWNER) of the person 2008 * @param {String} key The ID of the person to verify friendship 2009 * @param {undefined} opt_params Not used at this time. 2010 * @return {Object} A request object 2011 * @static 2012 * @memberOf MyOpenSpace.DataRequest 2013 */ 2014 MyOpenSpace.DataRequest.newFetchPersonFriendshipRequest = function(id, key, opt_parms) { 2015 return opensocial.Container.get().newFetchPersonFriendshipRequest(id, key, opt_parms); 2016 }; 2017 2018 /** 2019 * Creates an object to be used when sending to the server 2020 * @param {String} id The ID (VIEWER or OWNER) of the person 2021 * @param {Array} key The array of IDs of the people to verify friendship. 2022 * @param {undefined} opt_params Not used at this time. 2023 * @return {Object} A request object 2024 * @static 2025 * @memberOf MyOpenSpace.DataRequest 2026 */ 2027 MyOpenSpace.DataRequest.newFetchPeopleFriendshipRequest = function(id, key, opt_parms) { 2028 return opensocial.Container.get().newFetchPeopleFriendshipRequest(id, key, opt_parms); 2029 }; 2030 2031 /** 2032 * Creates an object to be used when sending to the server 2033 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the albums 2034 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the videos. 2035 * @return {Object} A request object 2036 * @static 2037 * @memberOf MyOpenSpace.DataRequest 2038 */ 2039 MyOpenSpace.DataRequest.newFetchVideosRequest = function(id, photo_id, opt_params) { 2040 return opensocial.Container.get().newFetchVideosRequest(id, photo_id, opt_params); 2041 }; 2042 2043 MyOpenSpace.DataRequest.prototype = { 2044 //maxRequestObjects: 40, 2045 //setAuthorization: function(template) { 2046 //opensocial.Container.get().getRequestProcessor().setAuthorization(template); 2047 //}, 2048 2049 allRequestsCompleteCallback_: function() {}, 2050 2051 getRequestObjects: function() { 2052 return this.requestObjects_; 2053 }, 2054 2055 add: function(request, opt_key) { // was: add: function(request, priority) { 2056 if(!this.busy_){ 2057 //priority = priority || MyOpenSpace.RequestProcessor_.WorkItem.Priority.NORMAL; 2058 //if(!opt_key) opt_key = request.type + "-" + request.parameters.id; 2059 opt_key ? request.key = opt_key : request.key = null; 2060 if("undefined" === typeof(opt_key) || !this.requestObjects_.has(opt_key)){ // check for duplicate entry 2061 //opensocial.Container.get().getRequestProcessor().addWorkItem(request); 2062 this.requestProcessor_.addWorkItem(request); 2063 var id = request.type; 2064 if(request.parameters){ 2065 if(request.parameters.id) id += "-" + request.parameters.id; 2066 else if(request.parameters.idSpec) id += "-" + request.parameters.idSpec; 2067 } 2068 opt_key ? this.requestObjects_.add(opt_key, request) : this.requestObjects_.add(id, request); 2069 this.requestObjectCount_++; 2070 } 2071 } 2072 }, 2073 send: function(opt_callback) { //TODO: is callback optional? why send a request if there's no callback? 2074 if(!this.busy_ && this.requestObjectCount_ > 0){ 2075 this.busy_ = true; 2076 if(opt_callback) this.allRequestsCompleteCallback_ = opt_callback; 2077 2078 opensocial.Container.get().requestData(this, opt_callback); 2079 } 2080 2081 }, 2082 newFetchPersonRequest: function(id, opt_params) { 2083 return opensocial.Container.get().newFetchPersonRequest(id, opt_params); 2084 }, 2085 newFetchPeopleRequest: function(id, opt_params) { 2086 return opensocial.Container.get().newFetchPeopleRequest(id, opt_params); 2087 }, 2088 newFetchGlobalAppDataRequest: function() { 2089 return opensocial.Container.get().newFetchGlobalAppDataRequest(); 2090 }, 2091 newFetchInstanceAppDataRequest: function() { 2092 return opensocial.Container.get().newFetchInstanceAppDataRequest(); 2093 }, 2094 newUpdateInstanceAppDataRequest: function() { 2095 return opensocial.Container.get().newUpdateInstanceAppDataRequest(); 2096 }, 2097 newFetchPersonAppDataRequest: function(id, keys, opt_params) { 2098 return opensocial.Container.get().newFetchPersonAppDataRequest(id, keys, opt_params); 2099 }, 2100 newUpdatePersonAppDataRequest: function(id, key, value) { 2101 return opensocial.Container.get().newUpdatePersonAppDataRequest(id, key, value); 2102 }, 2103 newFetchActivitiesRequest: function(idSpec, opt_params) { 2104 return opensocial.Container.get().newFetchActivitiesRequest(idSpec, opt_params); 2105 }, 2106 newRemovePersonAppDataRequest: function(id,keys){ 2107 return opensocial.Container.get().newRemovePersonAppDataRequest(id,keys); 2108 } 2109 }; 2110 2111 /** 2112 * @constructor 2113 * @name MyOpenSpace.DataRequest.RequestActions_ 2114 * @internal 2115 */ 2116 MyOpenSpace.DataRequest.RequestActions_ = function(dataRequest) { 2117 this.dataRequest_ = dataRequest; 2118 this.itemsProcessed_ = 0; 2119 this.dataResponseValues_ = {}; 2120 }; 2121 2122 /** 2123 * Does the logic for the requests and sets up callbacks 2124 * @memberOf MyOpenSpace.DataRequest 2125 * @private 2126 * @internal 2127 */ 2128 MyOpenSpace.DataRequest.RequestActions_.prototype = { 2129 itemsProcessed_: 0, 2130 dataResponseValues_: {}, 2131 errored_: false, 2132 getRequestId_: function getRequestId_(id) { 2133 var table = this.dataRequest_.ReqestIdTable_; 2134 if (typeof table === 'undefined' || table === null) { 2135 this.dataRequest_.ReqestIdTable_ = {}; 2136 table = this.dataRequest_.ReqestIdTable_; 2137 } 2138 var requestId = table[id]; 2139 if (typeof requestId === 'undefined') { 2140 table[id] = 0; 2141 requestId = ""; 2142 } 2143 else { 2144 table[id] += 1; 2145 requestId = "_" + table[id]; 2146 } 2147 return requestId; 2148 }, 2149 isViewerDenied: function(type, key) { 2150 if (gadgets.views.getParams().denyViewer) { 2151 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.UNAUTHORIZED, "errorMessage": "Permission denied to all viewer resources." }, type, true, key); 2152 return true; 2153 } 2154 else { 2155 return false; 2156 } 2157 }, 2158 /** 2159 * Internal method that handles fetch person requests 2160 * @internal 2161 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2162 * @param {Object} workitem 2163 */ 2164 "FETCH_PERSON": function FETCH_PERSON(workitem) { 2165 var personId = workitem.parameters.id; 2166 var type = MyOpenSpace.RequestType.FETCH_PERSON; 2167 2168 var url; 2169 var profileDetail = workitem.parameters.profileDetail; 2170 if (profileDetail.unsupported != null){ 2171 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "errorMessage": "Request contains not implemented fields:" + profileDetail.unsupported}, workitem.key, true); 2172 return; 2173 } 2174 2175 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2176 url = this.dataRequest_.endPoint_.Person.Viewer.replace("{DETAIL_TYPE}", profileDetail.fields); 2177 if (this.isViewerDenied(type, workitem.key)) return; 2178 } 2179 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2180 url = this.dataRequest_.endPoint_.Person.Owner.replace("{DETAIL_TYPE}", profileDetail.fields); 2181 } 2182 else { 2183 var results = ('' + personId).match(/^(?:myspace\.com:)?(\d+)$/); 2184 if (results === null || results.length === 0) { 2185 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, type, true, workitem.key); 2186 return; 2187 } 2188 url = this.dataRequest_.endPoint_.Person.ID.replace("{PERSON_ID}", results[1]); 2189 } 2190 this.invoke_(this, url, type, workitem.key); 2191 }, 2192 /** 2193 * Internal method that handles fetch people requests 2194 * @internal 2195 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2196 * @param {Object} workitem 2197 */ 2198 "FETCH_PEOPLE": function FETCH_PEOPLE(workitem) { 2199 var idSpec = idSpecMap(workitem.parameters.idSpec); 2200 var type = MyOpenSpace.RequestType.FETCH_PEOPLE; 2201 2202 var url; 2203 if (typeof (idSpec.errorCode) !== 'undefined') { 2204 this.addResponseItem_(idSpec, type, true, workitem.key); 2205 return; 2206 } 2207 2208 var first = workitem.parameters.first; 2209 var max = workitem.parameters.max; 2210 var filter = workitem.parameters.filter; 2211 var sort = workitem.parameters.sortOrder; 2212 var details = workitem.parameters.details; 2213 var sortToken = ""; 2214 var filterToken = ""; 2215 2216 //details 2217 if (typeof(details) !== 'undefined'){ 2218 this.addResponseItem_({ 2219 "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, 2220 "errorMessage": "opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS is not implemented." 2221 }, type, true, workitem.key); 2222 return; 2223 } 2224 2225 // paging 2226 var pagingError = this.getPagingError(first,max); 2227 if(pagingError !== "") 2228 { 2229 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": pagingError}, 2230 type, true, workitem.key); 2231 return; 2232 } 2233 var paging = this.mapPagingParams_(workitem.parameters.first, workitem.parameters.max); 2234 2235 // sorting 2236 if (typeof(sort) !== 'undefined') { 2237 if (opensocial.DataRequest.SortOrder.NAME === sort) { 2238 sortToken = this.dataRequest_.endPoint_.SortQueryString.replace("{SORT_BY}", "nickName").replace("{SORT_ORDER}", "asc"); 2239 } 2240 else if (MyOpenSpace.DataRequest.SortOrder.ID === sort){ 2241 sortToken = this.dataRequest_.endPoint_.SortQueryString.replace("{SORT_BY}", "id").replace("{SORT_ORDER}", "asc"); 2242 } 2243 else if (opensocial.DataRequest.SortOrder.TOP_FRIENDS === sort) { 2244 this.addResponseItem_({ 2245 "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, 2246 "errorMessage": "Sort order value opensocial.DataRequest.SortOrder.TOP_FRIENDS is not implemented. If you want to filter top friends use opensocial.DataRequest.PeopleRequestFields.FILTER instead." 2247 }, type, true, workitem.key); 2248 return; 2249 } 2250 else { 2251 this.addResponseItem_({ 2252 "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2253 "errorMessage": "Invalid sort order value." 2254 }, type, true, workitem.key); 2255 return; 2256 } 2257 } 2258 2259 // filter 2260 2261 2262 // we can only have one filter at a time, so if more than one are specified we need to create an order of precedence 2263 if (filter) { 2264 if (opensocial.DataRequest.FilterType.HAS_APP === filter) filterToken = "app"; 2265 else if (MyOpenSpace.DataRequest.FilterType.ONLINE_FRIENDS === filter) filterToken = "online"; 2266 else if (opensocial.DataRequest.FilterType.TOP_FRIENDS === filter) filterToken = "top"; 2267 else if (opensocial.DataRequest.FilterType.ALL === filter) filterToken = "all"; 2268 else if (opensocial.DataRequest.FilterType.IS_FRIENDS_WITH === filter){ 2269 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "errorMessage": "opensocial.DataRequest.FilterType.IS_FRIENDS_WITH is not implemented." }, 2270 type, true, workitem.key); 2271 return; 2272 } 2273 else{ 2274 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "invalid filter." }, 2275 type, true, workitem.key); 2276 return; 2277 } 2278 filterToken = this.dataRequest_.endPoint_.FilterQueryString.replace("{FILTER}", filterToken); 2279 } 2280 2281 if ("number" === typeof (idSpec) || !isNaN(parseInt(idSpec, 10))) { 2282 url = this.dataRequest_.endPoint_.People.ID.replace("{PERSON_ID}", idSpec); 2283 } 2284 else if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER_FRIENDS) { 2285 url = this.dataRequest_.endPoint_.People.ViewerFriends.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]) + filterToken + sortToken; 2286 if (this.isViewerDenied(type, workitem.key)) return; 2287 } 2288 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER_FRIENDS) { 2289 url = this.dataRequest_.endPoint_.People.OwnerFriends.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]) + filterToken + sortToken; 2290 } 2291 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER) { 2292 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, 2293 "errorMessage": "Unsupported idSpec. To get owner information use fetchPersonRequest." },type, true, workitem.key); 2294 return; 2295 } 2296 else if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER) { 2297 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, 2298 "errorMessage": "Unsupported idSpec To get viewer information use fetchPersonRequest." }, 2299 type, true, workitem.key); 2300 } 2301 else { 2302 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2303 "errorMessage": "Unsupported idSpec" }, 2304 type, true, workitem.key); 2305 return; 2306 } 2307 2308 this.invoke_(this, url, type, workitem.key); 2309 }, 2310 /** 2311 * Internal method that handles fetch indicators requests 2312 * @internal 2313 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2314 * @param {Object} workitem 2315 */ 2316 "FETCH_INDICATORS": function FETCH_INDICATORS(workitem) { 2317 var personId = workitem.parameters.id; 2318 var type = MyOpenSpace.RequestType.FETCH_INDICATORS; 2319 2320 var url; 2321 2322 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2323 url = this.dataRequest_.endPoint_.Indicators.Viewer; 2324 if (this.isViewerDenied(type, workitem.key)) return; 2325 } 2326 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2327 url = this.dataRequest_.endPoint_.Indicators.Owner; 2328 } 2329 else { 2330 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" },type, true, workitem.key); 2331 return; 2332 } 2333 this.invoke_(this, url, type, workitem.key); 2334 }, 2335 /** 2336 * Internal method that handles fetch person status requests 2337 * @internal 2338 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2339 * @param {Object} workitem 2340 */ 2341 "FETCH_PERSON_STATUS": function FETCH_PERSON_STATUS(workitem) { 2342 var personId = workitem.parameters.id; 2343 var type = MyOpenSpace.RequestType.FETCH_PERSON_STATUS; 2344 2345 var url; 2346 2347 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2348 url = this.dataRequest_.endPoint_.PersonStatus.Viewer; 2349 if (this.isViewerDenied(type, workitem.key)) return; 2350 } 2351 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2352 url = this.dataRequest_.endPoint_.PersonStatus.Owner; 2353 } 2354 else { 2355 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2356 type, true,workitem.key); 2357 return; 2358 } 2359 this.invoke_(this, url, type, workitem.key); 2360 }, 2361 /** 2362 * Internal method that handles fetch person mood requests 2363 * @internal 2364 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2365 * @param {Object} workitem 2366 */ 2367 "FETCH_PERSON_MOOD": function FETCH_PERSON_MOOD(workitem) { 2368 2369 var personId = workitem.parameters.id; 2370 var type = MyOpenSpace.RequestType.FETCH_PERSON_MOOD; 2371 2372 var url; 2373 2374 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2375 url = this.dataRequest_.endPoint_.PersonMood.Viewer; 2376 2377 if (this.isViewerDenied(type, workitem.key)) return; 2378 } 2379 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2380 url = this.dataRequest_.endPoint_.PersonMood.Owner; 2381 } 2382 else { 2383 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2384 type, true, workitem.key); 2385 return; 2386 } 2387 this.invoke_(this, url, type, workitem.key); 2388 }, 2389 /** 2390 * Internal method that handles fetch person friendship requests 2391 * @internal 2392 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2393 * @param {Object} workitem 2394 */ 2395 "FETCH_PERSON_FRIENDSHIP": function FETCH_PERSON_FRIENDSHIP(workitem) { 2396 var personId = workitem.parameters.id; 2397 var key = workitem.parameters.key; 2398 var type = MyOpenSpace.RequestType.FETCH_PERSON_FRIENDSHIP; 2399 2400 var url; 2401 2402 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2403 url = this.dataRequest_.endPoint_.Friendship.Viewer.replace("{PERSON_IDS}", key); 2404 if (this.isViewerDenied(type, workitem.key)) return; 2405 } 2406 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2407 url = this.dataRequest_.endPoint_.Friendship.Owner.replace("{PERSON_IDS}", key); 2408 } 2409 else { 2410 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2411 type, true, workitem.key); 2412 return; 2413 } 2414 this.invoke_(this, url, type, workitem.key); 2415 2416 }, 2417 /** 2418 * Internal method that handles fetch people friendship requests 2419 * @internal 2420 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2421 * @param {Object} workitem 2422 */ 2423 "FETCH_PEOPLE_FRIENDSHIP": function FETCH_PEOPLE_FRIENDSHIP(workitem) { 2424 var personId = workitem.parameters.id; 2425 var type = MyOpenSpace.RequestType.FETCH_PEOPLE_FRIENDSHIP; 2426 2427 var key = workitem.parameters.key; 2428 var url; 2429 2430 if (key.constructor != Array) { 2431 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Key must be an array." }, 2432 type, true, workitem.key); 2433 return; 2434 } 2435 if (key.length === 0) { 2436 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2437 "errorMessage": "Key must be an array with at least one element." }, type, true, workitem.key); 2438 return; 2439 } 2440 var idArray = []; 2441 for (var i = 0; i < key.length; i++) { 2442 2443 2444 var results = ('' + key[i]).match(/^(?:myspace\.com:)?(\d+)$/); 2445 if (results === null || results.length === 0) { 2446 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2447 "errorMessage": "Key user array element is not an user Id." }, 2448 type, true, workitem.key); 2449 return; 2450 } 2451 idArray[i] = results[1]; 2452 } 2453 2454 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2455 url = this.dataRequest_.endPoint_.Friendship.Viewer.replace("{PERSON_IDS}", idArray.join(";")); 2456 if (this.isViewerDenied(type, workitem.key)) return; 2457 } 2458 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2459 url = this.dataRequest_.endPoint_.Friendship.Owner.replace("{PERSON_IDS}", idArray.join(";")); 2460 } 2461 else { 2462 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2463 type, true, workitem.key); 2464 return; 2465 } 2466 this.invoke_(this, url, type, workitem.key); 2467 }, 2468 /** 2469 * Internal method that handles fetch photo requests 2470 * @internal 2471 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2472 * @param {Object} workitem 2473 */ 2474 "FETCH_PHOTO": function FETCH_PHOTO(workitem) { 2475 var personId = workitem.parameters.id; 2476 var type = MyOpenSpace.RequestType.FETCH_PHOTO; 2477 2478 var url; 2479 2480 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2481 url = this.dataRequest_.endPoint_.Photo.Viewer.replace("{PHOTO_ID}", workitem.parameters.photo_id); 2482 if (this.isViewerDenied(type, workitem.key)) return; 2483 } 2484 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2485 url = this.dataRequest_.endPoint_.Photo.Owner.replace("{PHOTO_ID}", workitem.parameters.photo_id); 2486 } 2487 else { 2488 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2489 type, true, workitem.key); 2490 return; 2491 } 2492 this.invoke_(this, url, type, workitem.key); 2493 }, 2494 /** 2495 * Internal method that handles fetch photos requests 2496 * @internal 2497 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2498 * @param {Object} workitem 2499 */ 2500 "FETCH_PHOTOS": function FETCH_PHOTOS(workitem) { 2501 var personId = workitem.parameters.id; 2502 var albumId = workitem.parameters.album_id; 2503 var type = MyOpenSpace.RequestType.FETCH_PHOTOS; 2504 2505 //test to see if the page request is in the form first = a(n) +1 where n = max; 2506 var first = workitem.parameters.first; 2507 var max = workitem.parameters.max; 2508 var pagingError = this.getPagingError(first,max); 2509 if(pagingError !== "") 2510 { 2511 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": pagingError}, 2512 type, true, workitem.key); 2513 return; 2514 } 2515 var paging = this.mapPagingParams_(workitem.parameters.first, workitem.parameters.max); 2516 var url; 2517 2518 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2519 if (null !== albumId) { 2520 url = this.dataRequest_.endPoint_.AlbumPhotos.Viewer.replace("{ALBUM_ID}", albumId).replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2521 } 2522 else { 2523 url = this.dataRequest_.endPoint_.Photos.Viewer.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2524 } 2525 2526 if (this.isViewerDenied(type, workitem.key)) return; 2527 } 2528 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2529 if (null !== albumId) { 2530 url = this.dataRequest_.endPoint_.AlbumPhotos.Owner.replace("{ALBUM_ID}", albumId).replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2531 } 2532 else { 2533 url = this.dataRequest_.endPoint_.Photos.Owner.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2534 } 2535 } 2536 else { 2537 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2538 type, true, workitem.key); 2539 return; 2540 } 2541 2542 this.invoke_(this, url, type, workitem.key); 2543 }, 2544 /** 2545 * Internal method that handles fetch album requests 2546 * @internal 2547 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2548 * @param {Object} workitem 2549 */ 2550 "FETCH_ALBUM": function FETCH_ALBUM(workitem) { 2551 var personId = workitem.parameters.id; 2552 var type = MyOpenSpace.RequestType.FETCH_ALBUM; 2553 2554 var url; 2555 2556 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2557 url = this.dataRequest_.endPoint_.Album.Viewer.replace("{ALBUM_ID}", workitem.parameters.album_id); 2558 if (this.isViewerDenied(type, workitem.key)) return; 2559 } 2560 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2561 url = this.dataRequest_.endPoint_.Album.Owner.replace("{ALBUM_ID}", workitem.parameters.album_id); 2562 } 2563 else { 2564 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported id" }, 2565 type, true, workitem.key); 2566 return; 2567 } 2568 this.invoke_(this, url, type, workitem.key); 2569 }, 2570 /** 2571 * Internal method that handles fetch people albums requests 2572 * @internal 2573 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2574 * @param {Object} workitem 2575 */ 2576 "FETCH_ALBUMS": function FETCH_ALBUMS(workitem) { 2577 var personId = workitem.parameters.id; 2578 var type = MyOpenSpace.RequestType.FETCH_ALBUMS; 2579 //test to see if the page request is in the form first = a(n) +1 where n = max; 2580 var first = workitem.parameters.first; 2581 var max = workitem.parameters.max; 2582 var pagingError = this.getPagingError(first,max); 2583 if(pagingError !== "") 2584 { 2585 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": pagingError}, 2586 type, true, workitem.key); 2587 return; 2588 } 2589 var paging = this.mapPagingParams_(workitem.parameters.first, workitem.parameters.max); 2590 var url; 2591 2592 2593 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2594 url = this.dataRequest_.endPoint_.Albums.Viewer.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2595 2596 if (this.isViewerDenied(type, workitem.key)) return; 2597 } 2598 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2599 url = this.dataRequest_.endPoint_.Albums.Owner.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2600 } 2601 else { 2602 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported idSpec" }, 2603 type, true, workitem.key); 2604 return; 2605 } 2606 this.invoke_(this, url, type, workitem.key); 2607 }, 2608 /** 2609 * Internal method that handles fetch video requests 2610 * @internal 2611 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2612 * @param {Object} workitem 2613 */ 2614 "FETCH_VIDEO": function FETCH_VIDEO(workitem) { 2615 var personId = workitem.parameters.id; 2616 var url; 2617 var type = MyOpenSpace.RequestType.FETCH_VIDEO; 2618 2619 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2620 url = this.dataRequest_.endPoint_.Video.Viewer.replace("{VIDEO_ID}", workitem.parameters.video_id); 2621 if (this.isViewerDenied(type, workitem.key)) return; 2622 } 2623 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2624 url = this.dataRequest_.endPoint_.Video.Owner.replace("{VIDEO_ID}", workitem.parameters.video_id); 2625 } 2626 else { 2627 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported idSpec" }, 2628 type, true, workitem.key); 2629 return; 2630 } 2631 this.invoke_(this, url, type, workitem.key); 2632 }, 2633 /** 2634 * Internal method that handles fetch videos requests 2635 * @internal 2636 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2637 * @param {Object} workitem 2638 */ 2639 "FETCH_VIDEOS": function FETCH_VIDEOS(workitem) { 2640 var personId = workitem.parameters.id; 2641 var type = MyOpenSpace.RequestType.FETCH_VIDEOS; 2642 2643 var first = workitem.parameters.first; 2644 var max = workitem.parameters.max; 2645 var pagingError = this.getPagingError(first,max); 2646 2647 2648 if(pagingError !== "") 2649 { 2650 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": pagingError}, 2651 type, true, workitem.key); 2652 return; 2653 } 2654 var paging = this.mapPagingParams_(workitem.parameters.first, workitem.parameters.max); 2655 var url; 2656 2657 if (personId === opensocial.IdSpec.PersonId.VIEWER) { 2658 url = this.dataRequest_.endPoint_.Videos.Viewer.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2659 if (this.isViewerDenied(type, workitem.key)) return; 2660 } 2661 else if (personId === opensocial.IdSpec.PersonId.OWNER) { 2662 url = this.dataRequest_.endPoint_.Videos.Owner.replace("{PAGE}", paging[0]).replace("{SIZE}", paging[1]); 2663 } 2664 else { 2665 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported idSpec" }, 2666 type, true, workitem.key); 2667 return; 2668 } 2669 this.invoke_(this, url, type, workitem.key); 2670 }, 2671 /** 2672 * Internal method that handles fetch person data requests 2673 * @internal 2674 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2675 * @param {Object} workitem 2676 */ 2677 "FETCH_PERSON_DATA": function FETCH_PERSON_DATA(workitem) { 2678 var idSpec = idSpecMap(workitem.parameters.idSpec); 2679 var type = MyOpenSpace.RequestType.FETCH_PERSON_DATA; 2680 2681 if (typeof (idSpec.errorCode) !== 'undefined') { 2682 this.addResponseItem_(idSpec, type, true, workitem.key); 2683 return; 2684 } 2685 2686 var keys = workitem.parameters.keys || ""; 2687 var opt_params = workitem.parameters.opt_params; 2688 var getId = false; 2689 var requestId; 2690 var url; 2691 2692 var group; 2693 var arrayError = false; 2694 if (keys === "*") { 2695 keys = ""; 2696 } 2697 else if (keys.constructor === Array) { 2698 for (var i = 0; i < keys.length; i++) { 2699 if (keys[i] === "" || keys[i] === "*") { 2700 arrayError = true; 2701 break; 2702 } 2703 } 2704 keys = "/" + keys.join(';'); 2705 } 2706 else { 2707 requestId = "_" + keys; 2708 keys = "/" + keys; 2709 } 2710 2711 var pointer = this; 2712 2713 if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER) { 2714 url = this.dataRequest_.endPoint_.PersonAppData.Viewer.replace("{KEYS}", keys); 2715 if (this.isViewerDenied(type, workitem.key)) return; 2716 } 2717 else if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER_FRIENDS) { 2718 url = this.dataRequest_.endPoint_.PersonAppData.ViewerFriends.replace("{KEYS}", keys); 2719 if (this.isViewerDenied(type, workitem.key)) return; 2720 } 2721 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER) { 2722 group = MyOpenSpace.Group.OWNER_APP_DATA + fetchOwnerAppDataRequestId; 2723 url = this.dataRequest_.endPoint_.PersonAppData.Owner.replace("{KEYS}", keys); 2724 } 2725 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER_FRIENDS) { 2726 url = this.dataRequest_.endPoint_.PersonAppData.OwnerFriends.replace("{KEYS}", keys); 2727 } 2728 else { 2729 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported idSpec" }, 2730 type, true, workitem.key); 2731 return; 2732 } 2733 if (arrayError) { 2734 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2735 "errorMessage": "Invalid key array element. Array can contain neither empty string nor '*'. " }, type, true, workitem.key); 2736 return; 2737 } 2738 this.invoke_(this, url, type, workitem.key, opt_params); 2739 }, 2740 /** 2741 * Internal method that handles update person data requests 2742 * @internal 2743 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2744 * @param {Object} workitem 2745 */ 2746 "UPDATE_PERSON_DATA": function UPDATE_PERSON_DATA(workitem) { 2747 var idSpec = workitem.parameters.id; 2748 var type = MyOpenSpace.RequestType.UPDATE_PERSON_DATA; 2749 2750 var url; 2751 2752 if (!validateAppDataKeyName(workitem.parameters.key)) { // bad key name 2753 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 2754 "errorMessage": "AppData key names can only consist of alphanumerics, dots, dashes and underscores." }, type, true, workitem.key); 2755 return; 2756 } 2757 2758 var getInvalidJsonErrorObject = function(){ 2759 return { "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "AppData value must be valid JSON." }; 2760 }; 2761 2762 //if it's an object, stringify it, then try to jsonify it 2763 if("object" === typeof(workitem.parameters.value)){ 2764 workitem.parameters.value = gadgets.json.stringify(workitem.parameters.value); 2765 if(!gadgets.json.parse(workitem.parameters.value)) { 2766 this.addResponseItem_(getInvalidJsonErrorObject(), workitem.parameters.key, true); 2767 return; 2768 } 2769 } 2770 else if("string" === typeof(workitem.parameters.value)){ 2771 if (!gadgets.json.parse(workitem.parameters.value)) { 2772 this.addResponseItem_(getInvalidJsonErrorObject(), type, true, workitem.parameters.key); 2773 return; 2774 } 2775 } 2776 else{ 2777 this.addResponseItem_(getInvalidJsonErrorObject(), type, true, workitem.parameters.key); 2778 return; 2779 } 2780 2781 2782 2783 this.dataRequest_.params = workitem.parameters.key + "=" + workitem.parameters.value; 2784 if (idSpec === opensocial.IdSpec.PersonId.VIEWER) { 2785 url = this.dataRequest_.endPoint_.PersonAppData.Viewer.replace("{KEYS}", ""); 2786 2787 if (this.isViewerDenied(type, workitem.key)) return; 2788 } 2789 else { 2790 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "errorMessage": "Unsupported idSpec" }, 2791 type, true, workitem.key); 2792 return; 2793 } 2794 this.invoke_(this, url, type, workitem.key); 2795 }, 2796 /** 2797 * Internal method that handles remove person data requests 2798 * @internal 2799 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2800 * @param {Object} workitem 2801 */ 2802 "REMOVE_PERSON_DATA": function REMOVE_PERSON_DATA(workitem) { 2803 var keys = workitem.parameters.keys || ""; 2804 var type = MyOpenSpace.RequestType.REMOVE_PERSON_DATA; 2805 2806 var requestId; 2807 var url; 2808 2809 2810 if (keys === "*" || keys === "") { 2811 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, 2812 "errorMessage": "You must supply a key or an array of keys to remove, note that * isn't implemented." }, 2813 type, true, workitem.key); 2814 return; 2815 } 2816 else if (keys.constructor === Array) { 2817 keys = "/" + keys.join(';'); 2818 } 2819 else { 2820 requestId = "_" + keys; 2821 keys = "/" + keys; 2822 } 2823 2824 var id = workitem.parameters.id; 2825 var pointer = this; 2826 2827 if (id === opensocial.IdSpec.PersonId.VIEWER) { 2828 url = this.dataRequest_.endPoint_.PersonAppData.Viewer.replace("{KEYS}", keys); 2829 if (this.isViewerDenied(type, workitem.key)) return; 2830 } 2831 else { 2832 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "errorMessage": "Unsupported idSpec" }, 2833 type, true, workitem.key); 2834 return; 2835 } 2836 this.invoke_(this, url, type, workitem.key); 2837 }, 2838 /** 2839 * Internal method that handles fetch activities requests 2840 * @internal 2841 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2842 * @param {Object} workitem 2843 */ 2844 "FETCH_ACTIVITIES": function FETCH_ACTIVITIES(workitem) { 2845 var idSpec = idSpecMap(workitem.parameters.idSpec); 2846 var type = MyOpenSpace.RequestType.FETCH_ACTIVITIES; 2847 2848 if (typeof (idSpec.errorCode) !== 'undefined') { 2849 this.addResponseItem_(idSpec, type, true, workitem.key); 2850 return; 2851 } 2852 2853 var url; 2854 2855 if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER) { 2856 url = this.dataRequest_.endPoint_.Activities.Viewer; 2857 if (this.isViewerDenied(type, workitem.key)) return; 2858 } 2859 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER) { 2860 url = this.dataRequest_.endPoint_.Activities.Owner; 2861 } 2862 else if (idSpec === MyOpenSpace.IdSpecMapping_.VIEWER_FRIENDS) { 2863 url = this.dataRequest_.endPoint_.Activities.ViewerFriends; 2864 if (this.isViewerDenied(type, workitem.key)) return; 2865 } 2866 else if (idSpec === MyOpenSpace.IdSpecMapping_.OWNER_FRIENDS) { 2867 url = this.dataRequest_.endPoint_.Activities.OwnerFriends; 2868 } 2869 else { 2870 this.addResponseItem_({ "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Unsupported idSpec" }, 2871 type, true, workitem.key); 2872 return; 2873 } 2874 this.invoke_(this, url, type, workitem.key); 2875 //this.addResponseItem_({"errorCode":opensocial.ResponseItem.Error.NOT_IMPLEMENTED,"errorMessage":"Fetch activities not implemented."},"FETCH_ACTIVITIES",true); 2876 }, 2877 /** 2878 * Internal utility method that handles verify pagin values 2879 * @internal 2880 * @memberOf MyOpenSpace.DataRequest.RequestActions_ 2881 * @param {Object} first 2882 * @param {Object} max 2883 */ 2884 getPagingError : function(first,max) 2885 { 2886 if(isNaN(first) && first !=="") 2887 { 2888 return ("Paging Error: first must be an integer"); 2889 } 2890 2891 if(isNaN(max) && max !=="") 2892 { 2893 return ("Paging Error: max must be an integer"); 2894 } 2895 2896 if(first <=0 && first !=="") 2897 { 2898 return ("Paging Error: first must be a positive integer greater than zero");; 2899 } 2900 2901 if(max <= 0 && max !=="") 2902 { 2903 return ("Paging Error: max must be a positive integer greater than zero");; 2904 } 2905 2906 if(((first%max !==1) && max != 1 && !(first === "" || max === ""))) 2907 { 2908 return ("Paging Error: paging data must be in the form of max = n and first = x(n) + 1 where x is any positive integer. i.e max=5, first= 2(5)+1 =11"); 2909 } 2910 2911 return ""; 2912 }, 2913 2914 mapPagingParams_: function(first, max) { 2915 if (first === null || typeof (first) === "undefined" || first < 1) first = 1; 2916 if (max === null || typeof (max) === "undefined" || max < 1 || max > MyOpenSpace.DefaultPageSize) max = MyOpenSpace.DefaultPageSize; 2917 2918 // page is not 0 indexed, it starts at 1 2919 var page_size = max; 2920 var page = Math.floor(first / page_size); 2921 if((first%page_size) !== 0) 2922 page += 1; 2923 return [page, page_size]; 2924 }, 2925 invoke_: function(requestActions, url, type, opt_key, opt_params) { 2926 var callback = function(user, errored, opt_key) { 2927 requestActions.addResponseItem_(user, type, errored, opt_key); 2928 }; 2929 var dataRequestAction = requestActions.dataRequest_; 2930 var method = "GET"; 2931 if (type === MyOpenSpace.RequestType.UPDATE_PERSON_DATA) method = "PUT"; 2932 if (type === MyOpenSpace.RequestType.REMOVE_PERSON_DATA) method = "DELETE"; 2933 2934 dataRequestAction.method = method; 2935 dataRequestAction.endPoint = url; 2936 if (method !== "PUT") { 2937 dataRequestAction.params = {}; 2938 } 2939 2940 if (opt_params && opt_params.useCache) { 2941 if (APICache.isCached(dataRequestAction.endPoint)) { 2942 var lifetime = opt_params.refreshInterval || 0; 2943 if (opt_params.refreshInterval > 0) { 2944 lifetime = opt_params.refreshInterval * 1000; 2945 } 2946 if (!APICache.isExpired(dataRequestAction.endPoint, lifetime)) { 2947 callback(APICache.retrieve(dataRequestAction.endPoint), false, opt_key); 2948 return; 2949 } 2950 } 2951 } 2952 2953 MyOpenSpace.Ajax.sendRequest(dataRequestAction, type, completed_, errored_, true, opt_key); 2954 function completed_(response, type, opt_key) { 2955 var error = null; 2956 var result = null; 2957 var map = new MyOpenSpace.DataMapper_(); 2958 if (type === MyOpenSpace.RequestType.REMOVE_PERSON_DATA || type === MyOpenSpace.RequestType.UPDATE_PERSON_DATA ){ 2959 callback(null, false, opt_key); 2960 return; 2961 } 2962 else if(type === MyOpenSpace.RequestType.FETCH_PERSON_DATA){ 2963 var encoding = opensocial.EscapeType.HTML_ESCAPE; 2964 if (typeof (opt_params) !== "undefined") { 2965 encoding = opt_params[opensocial.DataRequest.DataRequestFields.ESCAPE_TYPE]; 2966 if (typeof (opt_params) === "undefined") { 2967 encoding = opensocial.EscapeType.HTML_ESCAPE; 2968 } 2969 } 2970 result = map.mapData[MyOpenSpace.RequestType.FETCH_PERSON_DATA](response, encoding); 2971 } 2972 else{ 2973 result = map.mapData[type](response); 2974 } 2975 if (null === result) { 2976 callback({ "errorCode": opensocial.ResponseItem.Error.INTERNAL_ERROR, "errorMessage": "Unable to map entity" }, true, opt_key); 2977 } else { 2978 // short circuit for only cachable types here 2979 APICache.add(dataRequestAction.endPoint, result); 2980 callback(result, false, opt_key); //callback:pointer.addResponseItem_(user, 'VIEWER_FRIENDS'); 2981 } 2982 } 2983 2984 function errored_(response, opt_key) { 2985 callback(response, true, opt_key); 2986 } 2987 2988 }, 2989 2990 2991 addResponseItem_: function(item, type, errored, opt_key) { 2992 var ri; 2993 if (errored) { 2994 //this._addError(item,key); 2995 ri = opensocial.Container.get().newResponseItem(this.dataRequest_, null, item.errorCode, item.errorMessage); // TODO: what to send in for data? 2996 this.errored_ = true; 2997 } 2998 else 2999 ri = opensocial.Container.get().newResponseItem(this.dataRequest_, item, "", ""); 3000 3001 var responseKey; 3002 if (typeof(opt_key) === 'undefined' || opt_key === null){ 3003 responseKey = type + this.getRequestId_(type); 3004 } 3005 else{ 3006 responseKey = opt_key; 3007 } 3008 this.dataResponseValues_[responseKey] = ri; 3009 this.itemsProcessed_++; 3010 3011 //check to see if we're all done 3012 if (this.itemsProcessed_ === this.dataRequest_.requestObjectCount_) { 3013 this.dataRequest_.ReqestIdTable_ = null; 3014 this.dataRequest_.requestObjectCount_ = 0; 3015 this.dataRequest_.requestObjects_ = new MyOpenSpace.Hash(); 3016 this.dataRequest_.busy_ = false; 3017 this.dataRequest_.allRequestsCompleteCallback_(opensocial.Container.get().newDataResponse(this.dataResponseValues_, this.errored_)); 3018 } 3019 else if (this.dataRequest_.requestProcessor_.executionModel_ === MyOpenSpace.RequestProcessor_.ExecutionModel_.SERIAL) 3020 this.dataRequest_.requestProcessor_.startProcessing(); 3021 } 3022 }; 3023 /** 3024 * @constructor MyOpenSpace.EndPoint - namespace definition only 3025 */ 3026 if (typeof(MyOpenSpace.EndPoint) == "undefined") MyOpenSpace.EndPoint = {}; 3027 3028 /** 3029 * @class 3030 * @name MyOpenSpace.EndPoint 3031 * @internal 3032 * Represents myspace's api endpoints, which are secured outside and around the container. 3033 * Tokenization is to be removed once tokens are implemented. 3034 */ 3035 MyOpenSpace.EndPoint = { 3036 /** 3037 * @internal 3038 * @memberOf MyOpenSpace.EndPoint 3039 * Top level Domain for api endpoints. 3040 */ 3041 Server: { 3042 /** 3043 * @internal 3044 * @memberOf MyOpenSpace.EndPoint.Server 3045 * Domain used for testing locally. 3046 */ 3047 Localhost: "http://localhost", 3048 3049 /** 3050 * @internal 3051 * @memberOf MyOpenSpace.EndPoint.Server 3052 * Domain used for testing locally. 3053 */ 3054 Development: "http://local-api.myspace.com", 3055 3056 /** 3057 * @internal 3058 * @memberOf MyOpenSpace.EndPoint.Server 3059 * Domain used for running apps on production. 3060 */ 3061 Production: "http://{SUBDOMAIN}api.msappspace.com" 3062 }, 3063 ServerApiMySpace:{ 3064 /** 3065 * @internal 3066 * @memberOf MyOpenSpace.EndPoint.ServerApiMySpace 3067 * Domain used for testing locally. 3068 */ 3069 Localhost: "http://localhost", 3070 /** 3071 * @internal 3072 * @memberOf MyOpenSpace.EndPoint.ServerApiMySpace 3073 * Domain used for testing locally. 3074 */ 3075 Development: "http://local-api.myspace.com", 3076 /** 3077 * @internal 3078 * @memberOf MyOpenSpace.EndPoint.ServerApiMySpace 3079 * Domain used for running apps on production. 3080 */ 3081 Production: "http://api.myspace.com" 3082 }, 3083 /** 3084 * @internal 3085 * @memberOf MyOpenSpace.EndPoint 3086 * RESTFUL endpoint for People 3087 */ 3088 People: { 3089 Viewer: "/api-v2.svc/json/people/@me/@self", 3090 Owner: "/api-v2.svc/json/people/{PERSON_ID}/@self", 3091 // ID: "/api-v2.svc/json/people/{PERSON_ID}/@self", 3092 ID: "/opensocial-api-v1.svc/JSON/opensocial/users/{PERSON_ID}", 3093 ViewerFriends: "/api-v2.svc/json/people/@me/@friends", 3094 OwnerFriends: "/api-v2.svc/json/people/{PERSON_ID}/@friends" 3095 3096 }, 3097 /** 3098 * @internal 3099 * @memberOf MyOpenSpace.EndPoint 3100 * RESTFUL endpoint for People 3101 */ 3102 Person: { 3103 Viewer: "/api-v2.svc/json/people/@me/@self", 3104 Owner: "/api-v2.svc/json/people/{PERSON_ID}/@self", 3105 ID: "/opensocial-api-v1.svc/JSON/opensocial/users/{PERSON_ID}" 3106 }, 3107 /** 3108 * @internal 3109 * @memberOf MyOpenSpace.EndPoint 3110 * RESTFUL endpoint for Indicators 3111 */ 3112 Indicators: { 3113 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/indicators", 3114 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/indicators" 3115 }, 3116 /** 3117 * @internal 3118 * @memberOf MyOpenSpace.EndPoint 3119 * RESTFUL endpoint for friendship status 3120 */ 3121 Friendship: { 3122 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/friendship/{PERSON_IDS}", 3123 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/friendship/{PERSON_IDS}" 3124 }, 3125 /** 3126 * @internal 3127 * @memberOf MyOpenSpace.EndPoint 3128 * RESTFUL endpoint for status 3129 */ 3130 PersonStatus: { 3131 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/status", 3132 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/status" 3133 }, 3134 /** 3135 * @internal 3136 * @memberOf MyOpenSpace.EndPoint 3137 * RESTFUL endpoint for mood 3138 */ 3139 PersonMood: { 3140 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/mood", 3141 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/mood" 3142 }, 3143 /** 3144 * @internal 3145 * @memberOf MyOpenSpace.EndPoint 3146 * RESTFUL endpoint for Albums 3147 */ 3148 Albums: { 3149 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/albums", 3150 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/albums" 3151 }, 3152 /** 3153 * @internal 3154 * @memberOf MyOpenSpace.EndPoint 3155 * RESTFUL endpoint for Album 3156 */ 3157 Album: { 3158 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/albums/{ALBUM_ID}", 3159 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/albums/{ALBUM_ID}" 3160 }, 3161 /** 3162 * @internal 3163 * @memberOf MyOpenSpace.EndPoint 3164 * RESTFUL endpoint for Videos 3165 */ 3166 Videos: { 3167 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/videos", 3168 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/videos" 3169 }, 3170 /** 3171 * @internal 3172 * @memberOf MyOpenSpace.EndPoint 3173 * RESTFUL endpoint for Video 3174 */ 3175 Video: { 3176 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/videos/{VIDEO_ID}", 3177 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/videos/{VIDEO_ID}" 3178 }, 3179 /** 3180 * @internal 3181 * @memberOf MyOpenSpace.EndPoint 3182 * RESTFUL endpoint for Photos 3183 */ 3184 Photos: { 3185 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/photos", 3186 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/photos" 3187 }, 3188 /** 3189 * @internal 3190 * @memberOf MyOpenSpace.EndPoint 3191 * RESTFUL endpoint for Photos from a particular album 3192 */ 3193 AlbumPhotos: { 3194 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/albums/{ALBUM_ID}/photos", 3195 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/albums/{ALBUM_ID}/photos" 3196 }, 3197 /** 3198 * @internal 3199 * @memberOf MyOpenSpace.EndPoint 3200 * RESTFUL endpoint for Photo 3201 */ 3202 Photo: { 3203 Viewer: "/opensocial-api-v1.svc/JSON/opensocial/{VIEWER}/photos/{PHOTO_ID}", 3204 Owner: "/opensocial-api-v1.svc/JSON/opensocial/{OWNER}/photos/{PHOTO_ID}" 3205 }, 3206 /** 3207 * @internal 3208 * @memberOf MyOpenSpace.EndPoint 3209 * JSONP endpoint for permissions 3210 */ 3211 Permissions: { 3212 Viewer: "/v1/users/{PERSON_ID}/apps.jsnp", 3213 Owner: "/v1/users/{PERSON_ID}/apps.jsnp" 3214 }, 3215 /** 3216 * @internal 3217 * @memberOf MyOpenSpace.EndPoint 3218 * RESTFUL endpoint for activities 3219 */ 3220 Activities: { 3221 Viewer: "/api-v2.svc/json/activities/@me/@self", 3222 Owner: "/api-v2.svc/json/activities/{PERSON_ID}/@self", 3223 ViewerFriends: "/api-v2.svc/json/activities/@me/@friends", 3224 OwnerFriends: "/api-v2.svc/json/activities/{PERSON_ID}/@friends", 3225 ViewerInsert: "/api-v2.svc/json/activities/@me/@self" 3226 }, 3227 /** 3228 * @internal 3229 * @memberOf MyOpenSpace.EndPoint 3230 * RESTFUL endpoint for Data Persistence 3231 */ 3232 PersonAppData: { 3233 Viewer: "/opensocial-api-v1.svc/XML/opensocial/{VIEWER}/appdata{KEYS}", 3234 ViewerFriends: "/opensocial-api-v1.svc/XML/opensocial/{VIEWER}/friends/appdata{KEYS}", 3235 Owner: "/opensocial-api-v1.svc/XML/opensocial/{OWNER}/appdata{KEYS}", 3236 OwnerFriends: "/opensocial-api-v1.svc/XML/opensocial/{OWNER}/friends/appdata{KEYS}", 3237 Global: "/opensocial-api-v1.svc/XML/opensocial/appdata/global{KEYS}" 3238 }, 3239 /** 3240 * @internal 3241 * @memberOf MyOpenSpace.EndPoint 3242 * Tokenized query string containing common params 3243 */ 3244 CommonQueryString: "opensocial_surface={OS_MODE}&ts={TIME_STAMP}", 3245 /** 3246 * @internal 3247 * @memberOf MyOpenSpace.EndPoint 3248 * Tokenized query string containing detail type used in Person/Profile endpoint 3249 */ 3250 DetailQueryString: "&fields={DETAIL_TYPE}", 3251 /** 3252 * @internal 3253 * @memberOf MyOpenSpace.EndPoint 3254 * Tokenized query string containing paging parameters 3255 */ 3256 PagingQueryString: "&page={PAGE}&page_size={SIZE}", 3257 /** 3258 * @internal 3259 * @memberOf MyOpenSpace.EndPoint 3260 * Tokenized query string containing paging parameters for v2 3261 */ 3262 PagingQueryStringV2: "&startIndex={PAGE}&count={SIZE}", 3263 /** 3264 * @internal 3265 * @memberOf MyOpenSpace.EndPoint 3266 * Tokenized query string containing filters: top, all, app, online -- used for Friends and TopFriends endpoints 3267 */ 3268 FilterQueryString: "&filterBy={FILTER}", 3269 /** 3270 * @internal 3271 * @memberOf MyOpenSpace.EndPoint 3272 * Tokenized query string containing filters: top, all, app, online -- used for Friends and TopFriends endpoints 3273 */ 3274 SortQueryString: "&sortBy={SORT_BY}&sortOrder={SORT_ORDER}", 3275 /** 3276 * @internal 3277 * @memberOf MyOpenSpace.EndPoint 3278 * Tokenized query string containing the format for v2 endpoints 3279 */ 3280 FormatQueryString: "&format=JSON", 3281 /** 3282 * @internal 3283 * @param {MyOpenSpace.EndPoint} endPoint The MyOpenSpace.EndPoint object to populate 3284 * @param {opensocial.DataRequest.PersonId} userInfo Should be an enum containing VIEWER and OWNER 3285 * @param {MyOpenSpace.Formats} format Currently being forced to JSON, as opposed to XML 3286 * @param {MyOpenSpace.OperationModes} operationMode The domain thats being used in this app 3287 * @param {String} osToken The authorization token for this request 3288 * @param {opensocial.Surface} osMode The surface the app is being rendered on 3289 * Inserts tokens into the various tokenized endpoint URIs 3290 */ 3291 Tokenized: function(endPoint, userInfo, osToken, osMode) { 3292 var server; 3293 var serverMySpace; 3294 3295 3296 var subdomain =""; 3297 var domainParts = location.hostname.split('.'); 3298 var numericExpression = /^[0-9]+$/; 3299 if(domainParts[0].match(numericExpression)) 3300 { 3301 subdomain = domainParts[0] + "."; 3302 } 3303 3304 if (location.hostname.match(/^localhost/)) { 3305 server = endPoint.Server.Localhost; 3306 serverMySpace = endPoint.ServerApiMySpace.Localhost; 3307 } 3308 else if (location.hostname.match(/^local-/)) { 3309 server = endPoint.Server.Development; 3310 serverMySpace = endPoint.ServerApiMySpace.Development; 3311 } 3312 else 3313 { 3314 server = endPoint.Server.Production; 3315 serverMySpace = endPoint.ServerApiMySpace.Production; 3316 } 3317 3318 server = server.replace("{SUBDOMAIN}",subdomain); 3319 3320 var timeStamp = new Date().getTime(); 3321 3322 var params = gadgets.views.getParams(); 3323 var ownerId = MyOpenSpace.PrefetchParameters.getParam("ownerid"); 3324 if ("undefined" === typeof (ownerId) && params) { 3325 ownerId = params.ownerId; 3326 } 3327 3328 endPoint.CommonQueryString = endPoint.CommonQueryString.replace("{OS_MODE}", osMode.getName()).replace("{TIME_STAMP}", timeStamp); 3329 3330 endPoint.Person.Viewer = server + endPoint.Person.Viewer + "?" + endPoint.CommonQueryString + endPoint.DetailQueryString + endPoint.FormatQueryString; 3331 endPoint.Person.Owner = server + endPoint.Person.Owner.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString + endPoint.DetailQueryString + endPoint.FormatQueryString; 3332 3333 endPoint.People.ID = server + endPoint.People.ID + "?" + endPoint.CommonQueryString + endPoint.FormatQueryString; 3334 endPoint.People.Viewer = server + endPoint.People.Viewer + "?" + endPoint.CommonQueryString + endPoint.FormatQueryString; 3335 endPoint.People.Owner = server + endPoint.People.Owner.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString + endPoint.FormatQueryString; 3336 endPoint.People.ViewerFriends = server + endPoint.People.ViewerFriends + "?" + endPoint.CommonQueryString + endPoint.PagingQueryStringV2 + endPoint.FormatQueryString; 3337 endPoint.People.OwnerFriends = server + endPoint.People.OwnerFriends.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryStringV2 + endPoint.FormatQueryString; 3338 3339 3340 endPoint.Indicators.Viewer = server + endPoint.Indicators.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3341 endPoint.Indicators.Owner = server + endPoint.Indicators.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3342 endPoint.PersonStatus.Viewer = server + endPoint.PersonStatus.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3343 endPoint.PersonStatus.Owner = server + endPoint.PersonStatus.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3344 endPoint.PersonMood.Viewer = server + endPoint.PersonMood.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3345 endPoint.PersonMood.Owner = server + endPoint.PersonMood.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3346 endPoint.Friendship.Viewer = server + endPoint.Friendship.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3347 endPoint.Friendship.Owner = server + endPoint.Friendship.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3348 3349 3350 3351 endPoint.Albums.Viewer = server + endPoint.Albums.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3352 endPoint.Albums.Owner = server + endPoint.Albums.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3353 endPoint.Album.Viewer = server + endPoint.Album.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3354 endPoint.Album.Owner = server + endPoint.Album.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3355 endPoint.Videos.Viewer = server + endPoint.Videos.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3356 endPoint.Videos.Owner = server + endPoint.Videos.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3357 endPoint.Video.Viewer = server + endPoint.Video.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3358 endPoint.Video.Owner = server + endPoint.Video.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3359 endPoint.Photos.Viewer = server + endPoint.Photos.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3360 endPoint.Photos.Owner = server + endPoint.Photos.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3361 endPoint.Photo.Viewer = server + endPoint.Photo.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3362 endPoint.Photo.Owner = server + endPoint.Photo.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3363 endPoint.AlbumPhotos.Viewer = server + endPoint.AlbumPhotos.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3364 endPoint.AlbumPhotos.Owner = server + endPoint.AlbumPhotos.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString + endPoint.PagingQueryString; 3365 endPoint.Activities.Viewer = server + endPoint.Activities.Viewer + "?" + endPoint.CommonQueryString, 3366 endPoint.Activities.Owner = server + endPoint.Activities.Owner.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString, 3367 endPoint.Activities.ViewerFriends = server + endPoint.Activities.ViewerFriends.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString, 3368 endPoint.Activities.OwnerFriends = server + endPoint.Activities.OwnerFriends.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString, 3369 endPoint.Activities.ViewerInsert = server + endPoint.Activities.ViewerInsert.replace("{PERSON_ID}", ownerId) + "?" + endPoint.CommonQueryString, 3370 endPoint.PersonAppData.Viewer = server + endPoint.PersonAppData.Viewer.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3371 endPoint.PersonAppData.ViewerFriends = server + endPoint.PersonAppData.ViewerFriends.replace("{VIEWER}", userInfo.VIEWER) + "?" + endPoint.CommonQueryString; 3372 endPoint.PersonAppData.Owner = server + endPoint.PersonAppData.Owner.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3373 endPoint.PersonAppData.OwnerFriends = server + endPoint.PersonAppData.OwnerFriends.replace("{OWNER}", userInfo.OWNER) + "?" + endPoint.CommonQueryString; 3374 endPoint.PersonAppData.Global = server + endPoint.PersonAppData.Global + "?" + endPoint.CommonQueryString; 3375 endPoint.Permissions.Viewer = serverMySpace + endPoint.Permissions.Viewer; 3376 endPoint.Permissions.Owner = serverMySpace + endPoint.Permissions.Owner; 3377 3378 return endPoint; 3379 } 3380 }; 3381 /** 3382 * MySpace extension of the opensocial.Environment object. 3383 * @constructor 3384 * @param {Array<string>} supportedPostToTargets A string array of supported PostTo targets 3385 * @param {MyOpenSpace.Application} app An object representing the current application executing in the container 3386 * @class 3387 * @name MyOpenSpace.Environment 3388 * @private 3389 * @internal 3390 */ 3391 MyOpenSpace.Environment = function(supportedPostToTargets, app){ 3392 var supportedMapped = []; 3393 for (var i in supportedPostToTargets) { 3394 switch (supportedPostToTargets[i]){ 3395 case MyOpenSpace.PostTo.Targets.SEND_MESSAGE: 3396 supportedMapped.push(opensocial.Message.Type.PRIVATE_MESSAGE); 3397 break; 3398 case MyOpenSpace.PostTo.Targets.BULLETINS: 3399 supportedMapped.push(opensocial.Message.Type.NOTIFICATION); 3400 break; 3401 case MyOpenSpace.PostTo.Targets.COMMENTS: 3402 supportedMapped.push(opensocial.Message.Type.PUBLIC_MESSAGE); 3403 break; 3404 default: 3405 supportedMapped.push(supportedPostToTargets[i]); 3406 break; 3407 } 3408 } 3409 this.supportedPostToTargets = supportedMapped; 3410 this.currentApplication = app; 3411 }; 3412 3413 /** 3414 * Accessor for the supportedPostToTargets array 3415 * @memberOf MyOpenSpace.Environment 3416 * @private 3417 */ 3418 MyOpenSpace.Environment.prototype.getSupportedPostToTargets = function(){ 3419 return this.supportedPostToTargets; 3420 }; 3421 /** 3422 * Accessor for the current Application executing in the environment 3423 * @memberOf MyOpenSpace.Environment 3424 * @private 3425 */ 3426 MyOpenSpace.Environment.prototype.getApplication = function(){ 3427 return this.currentApplication; 3428 }; 3429 3430 3431 3432 /** 3433 * The types of extended objects in this container. 3434 * @static 3435 * @class 3436 * @name MyOpenSpace.Environment.ObjectType 3437 */ 3438 MyOpenSpace.Environment.ObjectType = { 3439 /** 3440 * @member MyOpenSpace.Environment.ObjectType 3441 */ 3442 VIDEO : "VIDEO", 3443 /** 3444 * @member MyOpenSpace.Environment.ObjectType 3445 */ 3446 PHOTO : "PHOTO", 3447 /** 3448 * @member MyOpenSpace.Environment.ObjectType 3449 */ 3450 ALBUM : "ALBUM", 3451 /** 3452 * @member MyOpenSpace.Environment.ObjectType 3453 */ 3454 PERSON : "PERSON" 3455 };/** 3456 * RSS Support methods 3457 * @private 3458 */ 3459 if (typeof(MyOpenSpace.Feed) == "undefined") MyOpenSpace.Feed = { "Supported" : "RSS2.0", RSS2 : {} }; 3460 MyOpenSpace.Feed.RSS2 = { 3461 Channel : function (xmlFeed, summaryOnly, numEntries) { 3462 this.title; 3463 this.link; 3464 this.description; 3465 this.language; 3466 this.copyright; 3467 this.managingEditor; 3468 this.webMaster; 3469 this.pubDate; 3470 this.lastBuildDate; 3471 this.generator; 3472 this.docs; 3473 this.ttl; 3474 this.rating; 3475 3476 var chanElement = xmlFeed.getElementsByTagName("channel")[0]; 3477 var properties = new Array("title", "link", "description"); 3478 var tmpElement = null; 3479 for (var i=0; i<properties.length; i++) 3480 { 3481 tmpElement = chanElement.getElementsByTagName(properties[i])[0]; 3482 if (tmpElement!= null) 3483 this[properties[i]]=tmpElement.childNodes[0].nodeValue; 3484 } 3485 3486 numEntries = numEntries || 3; //default as in opensocialreference 3487 3488 3489 /*optional object properties*/ 3490 this.category; 3491 this.image; 3492 if (!summaryOnly) { 3493 this.items = new Array(); 3494 // var chanElement = xmlFeed.getElementsByTagName("channel")[0]; 3495 var itemElements = xmlFeed.getElementsByTagName("item"); 3496 numEntries = (numEntries < itemElements.length) ? numEntries : itemElements.length; 3497 for (var i=0; i<numEntries; i++) 3498 { 3499 Item = new MyOpenSpace.Feed.RSS2.Item(itemElements[i]); 3500 this.items.push(Item); 3501 } 3502 } 3503 var properties = ["title", "link", "description", "language", "copyright", "managingEditor", "webMaster", "pubDate", "lastBuildDate", "generator", "docs", "ttl", "rating"]; 3504 var tmpElement = null; 3505 for (var i=0; i<properties.length; i++) 3506 { 3507 tmpElement = chanElement.getElementsByTagName(properties[i])[0]; 3508 if (tmpElement!= null) 3509 this[properties[i]] =tmpElement.childNodes[0].nodeValue; 3510 } 3511 3512 this.category = new MyOpenSpace.Feed.RSS2.Category(chanElement.getElementsByTagName("category")[0]); 3513 this.image = new MyOpenSpace.Feed.RSS2.Image(chanElement.getElementsByTagName("image")[0]); 3514 3515 }, 3516 Category : function(categoryNode) 3517 { 3518 if (categoryNode == null) { 3519 this.domain = null; 3520 this.value = null; 3521 } else { 3522 this.domain = categoryNode.getAttribute("domain"); 3523 this.value = categoryNode.childNodes[0].nodeValue; 3524 } 3525 }, 3526 Image : function(imgElement) 3527 { 3528 if (imgElement == null) { 3529 this.url = null; 3530 this.link = null; 3531 this.width = null; 3532 this.height = null; 3533 this.description = null; 3534 } else { 3535 imgAttribs = ["url","title","link","width","height","description"]; 3536 for (var i=0; i<imgAttribs.length; i++) 3537 if (imgElement.getAttribute(imgAttribs[i]) != null) 3538 this[imgAttribs[i]] = imgElement.getAttribute(imgAttribs[i]); 3539 } 3540 }, 3541 Item : function(itemxml) 3542 { 3543 /*required*/ 3544 this.title; 3545 this.link; 3546 this.description; 3547 3548 /*optional*/ 3549 this.author; 3550 this.comments; 3551 this.pubDate; 3552 this.category; 3553 this.enclosure; 3554 this.guid; 3555 this.source; 3556 3557 var properties = ["title", "link", "description", "author", "comments", "pubDate"]; 3558 var tmpElement = null; 3559 for (var i=0; i<properties.length; i++) 3560 { 3561 tmpElement = itemxml.getElementsByTagName(properties[i])[0]; 3562 if (tmpElement != null) 3563 this[properties[i]] = tmpElement.childNodes[0].nodeValue; 3564 } 3565 3566 this.category = new MyOpenSpace.Feed.RSS2.Category(itemxml.getElementsByTagName("category")[0]); 3567 this.enclosure = new MyOpenSpace.Feed.RSS2.Enclosure(itemxml.getElementsByTagName("enclosure")[0]); 3568 this.guid = new MyOpenSpace.Feed.RSS2.Guid(itemxml.getElementsByTagName("guid")[0]); 3569 this.source = new MyOpenSpace.Feed.RSS2.Source(itemxml.getElementsByTagName("source")[0]); 3570 }, 3571 Enclosure : function(encElement) 3572 { 3573 if (encElement == null) { 3574 this.url = null; 3575 this.length = null; 3576 this.type = null; 3577 } else { 3578 this.url = encElement.getAttribute("url"); 3579 this.length = encElement.getAttribute("length"); 3580 this.type = encElement.getAttribute("type"); 3581 } 3582 }, 3583 Guid : function(guidElement) 3584 { 3585 if (guidElement == null) { 3586 this.isPermaLink = null; 3587 this.value = null; 3588 } else { 3589 this.isPermaLink = guidElement.getAttribute("isPermaLink"); 3590 this.value = guidElement.childNodes[0].nodeValue; 3591 } 3592 }, 3593 Source : function(srcElement) 3594 { 3595 if (srcElement == null) { 3596 this.url = null; 3597 this.value = null; 3598 } else { 3599 this.url = srcElement.getAttribute("url"); 3600 this.value = srcElement.childNodes[0].nodeValue; 3601 } 3602 } 3603 };/** 3604 * A class representing an FriendshipStatus. 3605 * @constructor 3606 * @private 3607 */ 3608 MyOpenSpace.Friendship = function() {}; 3609 3610 /** 3611 * The fields for MyOpenSpace.Friendship 3612 * @class 3613 * @name MyOpenSpace.Friendship.Field 3614 * @static 3615 */ 3616 MyOpenSpace.Friendship.Field = { 3617 /** 3618 * A boolean indicating if the person is friend. 3619 * @memberOf MyOpenSpace.Friendship.Field 3620 */ 3621 IS_FRIEND:"IS_FRIEND", 3622 3623 /** 3624 * A string indicating the friend id. 3625 * @memberOf MyOpenSpace.Friendship.Field 3626 */ 3627 FRIEND_ID:"FRIEND_ID" 3628 }; 3629 3630 /** 3631 * Returns the field specified by key 3632 * @param {String} key The key to search by 3633 * @return {MyOpenSpace.Friendship || undefined} The Frienship Field value if found, nothing otherwise. 3634 */ 3635 MyOpenSpace.Friendship.prototype.getField = function(key) { return this[key]; }; 3636 3637 /** 3638 * Writes a value to the field specified by the key 3639 * @param {String} key The key to search by. 3640 * @param {String} val The value to set. 3641 * @private 3642 * @private 3643 */ 3644 MyOpenSpace.Friendship.prototype.setField_ = function(key,val) { this[key] = val; };/** 3645 * Internal implementation of a simple hash table. 3646 * @private 3647 */ 3648 MyOpenSpace.Hash = function(){ 3649 this._hash = {}; 3650 this._num = 0; 3651 }; 3652 MyOpenSpace.Hash.prototype = { 3653 _hash:null, 3654 _num:null, 3655 /** 3656 * Add element to the hash 3657 * @param {Object} key 3658 * @param {Object} value 3659 * @private 3660 */ 3661 add:function(key, value){ 3662 this._hash[key] = value; 3663 this._num++; 3664 }, 3665 /** 3666 * Remove element from the hash 3667 * @param {Object} key 3668 * @private 3669 */ 3670 remove:function(key){ 3671 var val = null; 3672 if("undefined" !== typeof(this._hash[key])){ 3673 val = this._hash[key]; 3674 delete this._hash[key]; 3675 this._num--; 3676 } 3677 return val; 3678 }, 3679 /** 3680 * 3681 * @param {Object} key 3682 * @private 3683 */ 3684 get:function(key){ 3685 return _hash[key]; 3686 }, 3687 /** 3688 * @private 3689 */ 3690 size:function(){ 3691 return this._num; 3692 }, 3693 /** 3694 * 3695 * @param {Object} key 3696 * @private 3697 */ 3698 has:function(key){ 3699 if(!key) return false; 3700 return "undefined" !== typeof(this._hash[key]); 3701 } 3702 };/* ================================================================ 3703 * MyOpenSpace.Indicators 3704 * ================================================================ 3705 */ 3706 3707 3708 /** 3709 * A class representing an Indicators. 3710 * @constructor 3711 * @private 3712 */ 3713 MyOpenSpace.Indicators = function() {}; 3714 /** 3715 * The fields for MyOpenSpace.Indicators 3716 * @class 3717 * @name MyOpenSpace.Indicators.Field 3718 * @static 3719 */ 3720 MyOpenSpace.Indicators.Field = { 3721 /** 3722 * A boolean indicating the peroson has a mail. 3723 * @memberOf MyOpenSpace.Indicators.Field 3724 */ 3725 MAIL:"MAIL", 3726 3727 /** 3728 * A string containing the mail url. 3729 * @memberOf MyOpenSpace.Indicators.Field 3730 */ 3731 MAIL_URL:"MAIL_URL", 3732 3733 /** 3734 * A boolean indication the person has a birthday. 3735 * @memberOf MyOpenSpace.Indicators.Field 3736 */ 3737 BIRTHDAY:"BIRTHDAY", 3738 3739 /** 3740 * A string containing the birthday url. 3741 * @memberOf MyOpenSpace.Indicators.Field 3742 */ 3743 BIRTHDAY_URL:"BIRTHDAY_URL", 3744 3745 /** 3746 * A boolean indicating the person has a blog comment. 3747 * @memberOf MyOpenSpace.Indicators.Field 3748 */ 3749 BLOG_COMMENT:"BLOG_COMMENT", 3750 3751 /** 3752 * A string containing the blog comment url. 3753 * @memberOf MyOpenSpace.Indicators.Field 3754 */ 3755 BLOG_COMMENT_URL:"BLOG_COMMENT_URL", 3756 3757 /** 3758 * A boolean indicating the person has a blog subscrition post. 3759 * @memberOf MyOpenSpace.Indicators.Field 3760 */ 3761 BLOG_SUBSCRIPTION_POST:"BLOG_SUBSCRIPTION_POST", 3762 3763 /** 3764 * A string containing the blog subscription post url. 3765 * @memberOf MyOpenSpace.Indicators.Field 3766 */ 3767 BLOG_SUBSCRIPTION_POST_URL:"BLOG_SUBSCRIPTION_POST_URL", 3768 3769 /** 3770 * A boolean indicating the person has a comment. 3771 * @memberOf MyOpenSpace.Indicators.Field 3772 */ 3773 COMMENT:"COMMENT", 3774 3775 /** 3776 * A string containing the comment url. 3777 * @memberOf MyOpenSpace.Indicators.Field 3778 */ 3779 COMMENT_URL:"COMMENT_URL", 3780 3781 /** 3782 * A boolean indicating the person has a event invitation. 3783 * @memberOf MyOpenSpace.Indicators.Field 3784 */ 3785 EVENT_INVITATION:"EVENT_INVITATION", 3786 3787 /** 3788 * A string containing the event invitation url. 3789 * @memberOf MyOpenSpace.Indicators.Field 3790 */ 3791 EVENT_INVITATION_URL:"EVENT_INVITATION_URL", 3792 3793 /** 3794 * A boolean indicating the person has a friend request. 3795 * @memberOf MyOpenSpace.Indicators.Field 3796 */ 3797 FRIEND_REQUEST:"FRIEND_REQUEST", 3798 3799 /** 3800 * A string containing the friend request invitation url. 3801 * @memberOf MyOpenSpace.Indicators.Field 3802 */ 3803 FRIEND_REQUEST_URL:"FRIEND_REQUEST_URL", 3804 3805 /** 3806 * A boolean indicating the person has a group notification. 3807 * @memberOf MyOpenSpace.Indicators.Field 3808 */ 3809 GROUP_NOTIFICATION:"GROUP_NOTIFICATION", 3810 3811 /** 3812 * A string containing the group notification url. 3813 * @memberOf MyOpenSpace.Indicators.Field 3814 */ 3815 GROUP_NOTIFICATION_URL:"GROUP_NOTIFICATION_URL", 3816 3817 /** 3818 * A boolean indicating the person has a photo tag approval. 3819 * @memberOf MyOpenSpace.Indicators.Field 3820 */ 3821 PHOTO_TAG_APPROVAL:"PHOTO_TAG_APPROVAL", 3822 3823 /** 3824 * A string containing the photo tag approval url. 3825 * @memberOf MyOpenSpace.Indicators.Field 3826 */ 3827 PHOTO_TAG_APPROVAL_URL:"PHOTO_TAG_APPROVAL_URL", 3828 3829 /** 3830 * A boolean indicating the person has a picture comment. 3831 * @memberOf MyOpenSpace.Indicators.Field 3832 */ 3833 PICTURE_COMMENT:"PICTURE_COMMENT", 3834 3835 /** 3836 * A string containing the picture comment url. 3837 * @memberOf MyOpenSpace.Indicators.Field 3838 */ 3839 PICTURE_COMMENT_URL:"PICTURE_COMMENT_URL", 3840 3841 /** 3842 * A boolean indicating the person has a recently added friend. 3843 * @memberOf MyOpenSpace.Indicators.Field 3844 */ 3845 RECENTLY_ADDED_FRIEND:"RECENTLY_ADDED_FRIEND", 3846 3847 /** 3848 * A string containing the recently added friend url. 3849 * @memberOf MyOpenSpace.Indicators.Field 3850 */ 3851 RECENTLY_ADDED_FRIEND_URL:"RECENTLY_ADDED_FRIEND_URL", 3852 3853 /** 3854 * A boolean indicating the person has a video comment. 3855 * @memberOf MyOpenSpace.Indicators.Field 3856 */ 3857 VIDEO_COMMENT:"VIDEO_COMMENT", 3858 3859 /** 3860 * A string containing the video comment url. 3861 * @memberOf MyOpenSpace.Indicators.Field 3862 */ 3863 VIDEO_COMMENT_URL:"VIDEO_COMMENT_URL", 3864 3865 /** 3866 * A boolean indicating the person has a video process. 3867 * @memberOf MyOpenSpace.Indicators.Field 3868 */ 3869 VIDEO_PROCESS:"VIDEO_PROCESS", 3870 3871 /** 3872 * A string containing the video process url. 3873 * @memberOf MyOpenSpace.Indicators.Field 3874 */ 3875 VIDEO_PROCESS_URL:"VIDEO_PROCESS_URL" 3876 }; 3877 3878 /** 3879 * Returns the field specified by key 3880 * @param {String} key The key to search by 3881 * @return {MyOpenSpace.Indicators || undefined} The indicators if found, nothing otherwise. 3882 */ 3883 MyOpenSpace.Indicators.prototype.getField = function(key) { return this[key]; }; 3884 /** 3885 * Writes a value to the field specified by the key 3886 * @param {String} key The key to search by. 3887 * @param {String} val The value to set. 3888 * @private 3889 * @private 3890 */ 3891 MyOpenSpace.Indicators.prototype.setField_ = function(key,val) { this[key] = val; };//------------------------------------------// 3892 // Non namespaced global functions below 3893 //------------------------------------------// 3894 3895 /** 3896 * @ignore 3897 */ 3898 window.alert = function() { }; 3899 3900 /** 3901 * @ignore 3902 */ 3903 window.confirm = function() { }; 3904 3905 /** 3906 * @ignore 3907 */ 3908 function validateAppDataKeyName(keyName) { 3909 var validRE = /^([a-z0-9\-_\.])+$/i; 3910 return validRE.test(keyName); 3911 } 3912 3913 /** 3914 * @ignore 3915 */ 3916 Function.prototype.inherits = function(parentCtor) { 3917 function tempCtor() {}; 3918 tempCtor.prototype = parentCtor.prototype; 3919 this.superClass_ = parentCtor.prototype; 3920 this.prototype = new tempCtor(); 3921 this.prototype.constructor = this; 3922 }; 3923 3924 /** 3925 * @ignore 3926 * debugging utilities - reflect through an object's properties and trace values 3927 */ 3928 function reflect(obj, opt_dept, opt_currentDept){ 3929 opt_dept = (opt_dept == undefined) ? 0 : opt_dept; 3930 opt_currentDept = (opt_currentDept == undefined) ? 0 : opt_currentDept; 3931 //trace(obj); 3932 if (typeof(obj) == "object"){ 3933 for (var i in obj){ 3934 var levelPrefix = ''; 3935 for (var j = 0; j < opt_currentDept + 1; j++){ 3936 levelPrefix += " " 3937 } 3938 trace( levelPrefix + i + " -> " + obj[i] + "\n"); 3939 if (typeof(obj[i]) == "object"){ 3940 if (opt_dept > opt_currentDept){ 3941 reflect(obj[i], opt_dept, opt_currentDept + 1); 3942 } 3943 } 3944 } 3945 } 3946 } 3947 3948 var batchTrace = ""; 3949 /** 3950 * @ignore 3951 */ 3952 function tracePublicMembers(obj, propertyDepth) { 3953 propertyDepth = propertyDepth || 0; 3954 for (var prop in obj) { 3955 if (typeof(obj[prop]) == "function") return; 3956 3957 if (typeof(obj[prop]) == "object") 3958 { 3959 traceIndent(propertyDepth); 3960 dumpToBatch("<b>" + prop + "</b><BR>", propertyDepth); 3961 tracePublicMembers(obj[prop], propertyDepth+1); 3962 } 3963 else 3964 { 3965 if (prop.substring(prop.length-3) != "___") { 3966 traceIndent(propertyDepth); 3967 dumpToBatch("<i>" + prop + "</i>: " + obj[prop] + "<BR>", propertyDepth); 3968 } 3969 } 3970 } 3971 if (propertyDepth == 0) flushBatchTrace(); 3972 } 3973 3974 /** 3975 * @ignore 3976 */ 3977 function flushBatchTrace() { 3978 trace(batchTrace); 3979 batchTrace=""; 3980 } 3981 /** 3982 * @ignore 3983 */ 3984 function dumpToBatch(msg, depth) { 3985 if (depth == 0) { 3986 batchTrace = msg + batchTrace; 3987 } 3988 else 3989 { 3990 batchTrace += msg; 3991 } 3992 } 3993 /** 3994 * @ignore 3995 */ 3996 function traceIndent(depth) { 3997 if (depth>0) { 3998 dumpToBatch("|", depth); 3999 for (var i = 0;i<depth;i++) dumpToBatch("----", depth); 4000 dumpToBatch(">", depth); 4001 } 4002 } 4003 4004 var debugMessageDiv; 4005 var debugElementEnable; 4006 4007 /** 4008 * @ignore 4009 */ 4010 function trace(msg, opt_no_break) { 4011 if (typeof (debugElementEnable) === 'undefined') { 4012 debugMessageDiv = document.getElementById('debugMessages'); 4013 if (debugMessageDiv) { 4014 debugElementEnable = true; 4015 } 4016 else { 4017 debugElementEnable = false; 4018 } 4019 } 4020 4021 if (debugElementEnable) { 4022 opt_no_break = (opt_no_break) ? "" : "<BR>"; 4023 debugMessageDiv.innerHTML += opt_no_break + msg; 4024 } 4025 } 4026 4027 /** 4028 * @ignore 4029 */ 4030 function jsonp(url, name, query, allowCaching) { 4031 if (url.indexOf("?") > -1) 4032 url += "&jsonp=" 4033 else 4034 url += "?jsonp=" 4035 url += name + "&"; 4036 if (query) 4037 url += encodeURIComponent(query); 4038 if (allowCaching === false){ 4039 url += "&"; 4040 url += new Date().getTime().toString(); // prevent caching 4041 } 4042 4043 var script = document.createElement("script"); 4044 script.setAttribute("src", url); 4045 script.setAttribute("type", "text/javascript"); 4046 document.getElementsByTagName("head")[0].appendChild(script); 4047 } 4048 4049 /** 4050 * @ignore 4051 */ 4052 function idSpecMap(idspec) { 4053 4054 if (typeof (idspec.getField) === 'undefined') { 4055 4056 return { "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Invalid idSpec." }; 4057 } 4058 if ( 4059 typeof(idspec.getField(opensocial.IdSpec.Field.USER_ID)) === 'undefined') { 4060 return { "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "USER_ID was not provided." }; 4061 } 4062 4063 var userId = idspec.getField(opensocial.IdSpec.Field.USER_ID); 4064 var networkDistance = 0; 4065 if (typeof(idspec.getField(opensocial.IdSpec.Field.NETWORK_DISTANCE)) !== 'undefined') { 4066 if (typeof(idspec.getField(opensocial.IdSpec.Field.NETWORK_DISTANCE)) !== 'number') { 4067 return { 4068 "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 4069 "errorMessage": "NETWORK_DISTANCE must be an integer." 4070 }; 4071 } 4072 networkDistance = idspec.getField(opensocial.IdSpec.Field.NETWORK_DISTANCE); 4073 if (networkDistance < 0 || networkDistance > 1) { 4074 return { 4075 "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 4076 "errorMessage": "NETWORK_DISTANCE must be 0 or 1." 4077 }; 4078 } 4079 } 4080 else if (typeof(idspec.getField(opensocial.IdSpec.Field.GROUP_ID)) !== 'undefined') { 4081 var groupId = idspec.getField(opensocial.IdSpec.Field.GROUP_ID); 4082 if (groupId === "FRIENDS"){ 4083 networkDistance = 1; 4084 } 4085 else if (groupId === "SELF"){ 4086 networkDistance = 0; 4087 } 4088 else{ 4089 return { 4090 "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, 4091 "errorMessage": "GROUP_ID is not valid accepted values are FRIENDS or SELF."}; 4092 } 4093 } 4094 4095 if (userId === opensocial.IdSpec.PersonId.OWNER) { 4096 if (networkDistance === 0) { 4097 return MyOpenSpace.IdSpecMapping_.OWNER; 4098 } 4099 else if (networkDistance === 1) { 4100 return MyOpenSpace.IdSpecMapping_.OWNER_FRIENDS; 4101 } 4102 } 4103 else if (userId === opensocial.IdSpec.PersonId.VIEWER) { 4104 if (networkDistance === 0) { 4105 return MyOpenSpace.IdSpecMapping_.VIEWER; 4106 } 4107 else if (networkDistance === 1) { 4108 return MyOpenSpace.IdSpecMapping_.VIEWER_FRIENDS; 4109 } 4110 } 4111 else if (userId.constructor === Array) { 4112 if (networkDistance > 0) { 4113 return { "errorCode": opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "errorMessage": "NETWORK_DISTANCE greater than 0 is not been implemented for arrays of Ids." }; 4114 } 4115 var idArray = []; 4116 for (var i in userId) { 4117 var results = ('' + userId[i]).match(/^(?:myspace\.com:)?(\d+)$/); 4118 if (results === null || results.length === 0) { 4119 return { "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "opensocial.IdSpec.Field.USER_ID array contains invalid elements." }; 4120 } 4121 idArray[i] = results[1]; 4122 } 4123 return idArray; 4124 } 4125 else { 4126 var results = ('' + userId).match(/^(?:myspace\.com:)?(\d+)$/); 4127 if (results === null || results.length === 0) { 4128 return { "errorCode": opensocial.ResponseItem.Error.BAD_REQUEST, "errorMessage": "Invalid opensocial.IdSpec.Field.USER_ID value." }; 4129 } 4130 return results[1]; 4131 } 4132 4133 } 4134 4135 /** 4136 * Borrowed from prototype 4137 * @ignore 4138 */ 4139 var Try = { 4140 /** 4141 * @function 4142 * @param Array of statements to evaluate for returnValues. 4143 * @ignore 4144 */ 4145 these: function() { 4146 var returnValue; 4147 4148 for (var i = 0, length = arguments.length; i < length; i++) { 4149 var lambda = arguments[i]; 4150 try { 4151 returnValue = lambda(); 4152 break; 4153 } catch (e) {} 4154 } 4155 4156 return returnValue; 4157 } 4158 }; 4159 4160 /* 4161 * API cache hashtable, used for REST calls to API only 4162 * @class 4163 * @private 4164 * @static 4165 */ 4166 var APICache = { 4167 init: function() { 4168 if (this.cache == null) { 4169 this.cache = new MyOpenSpace.Hash(); 4170 this.timestamps = {}; 4171 } 4172 }, 4173 add: function(key, value) { 4174 if (!key || !value) return; 4175 this.cache[key] = value; 4176 this.timestamps[key] = new Date().getTime(); 4177 4178 }, 4179 isCached : function(key) { 4180 if(!key) return false; 4181 return "undefined" !== typeof(this.cache[key]); 4182 }, 4183 retrieve : function (key) { 4184 if (!key) return; 4185 return this.cache[key]; 4186 }, 4187 isExpired : function(key, timeToLive) { 4188 if(!key || !timeToLive) return; 4189 if (timeToLive == 0) return false; 4190 var lifespan = new Date().getTime() - this.timestamps[key]; 4191 return (lifespan > timeToLive) ? true : false; 4192 } 4193 4194 4195 };/** 4196 * The MySpace container class, extends opensocial.Container. Use opensocial.Container.get() to retrieve this singleton. 4197 * @constructor 4198 */ 4199 MyOpenSpace.MySpaceContainer = function() { 4200 if (gadgets.util.getUrlParameters().opensocial_surface) { 4201 //HACK-ISH 4202 gadgets.util.getUrlParameters().views = gadgets.util.getUrlParameters().opensocial_surface.toUpperCase(); 4203 } 4204 else { 4205 gadgets.util.getUrlParameters().views = ""; 4206 } 4207 4208 var config = {}; 4209 var supported_views = {}; 4210 supported_views["default"] = new gadgets.views.View(gadgets.views.ViewType.CANVAS, true); 4211 supported_views[gadgets.views.ViewType.CANVAS] = new gadgets.views.View(gadgets.views.ViewType.CANVAS, true); 4212 supported_views[gadgets.views.ViewType.PROFILE] = new gadgets.views.View(gadgets.views.ViewType.PROFILE, false); 4213 supported_views[gadgets.views.ViewType.HOME] = new gadgets.views.View(gadgets.views.ViewType.HOME, false); 4214 config["views"] = supported_views; 4215 4216 var uriFragment = window.location.hash; 4217 if (uriFragment && uriFragment.length >= 0) { 4218 uriFragment = uriFragment.substring(1, uriFragment.length); 4219 if (uriFragment.indexOf("&") >= 0) { 4220 uriFragment = uriFragment.substring(0, uriFragment.indexOf("&")); 4221 } 4222 } 4223 this.osToken_ = uriFragment || gadgets.util.getUrlParameters().opensocial_token; 4224 4225 var io_config = {}; 4226 4227 var proxyUrl = "/proxy/relay.proxy?opensocial_token=" + this.osToken_ + "&refresh=%refresh%&opensocial_url=%url%"; 4228 io_config["proxyUrl"] = proxyUrl; 4229 //Note: we do not use the jsonProxyUrl in our code. 4230 io_config["jsonProxyUrl"] = proxyUrl; //"relay/relay.proxy"; 4231 config["core.io"] = io_config; 4232 4233 gadgets.config.init(config); 4234 4235 this.prefs = new gadgets.Prefs(); 4236 4237 APICache.init(); 4238 4239 this.osMode_ = gadgets.views.getCurrentView(); 4240 4241 this.params_ = {}; 4242 4243 var urlParams = gadgets.util.getUrlParameters(); 4244 4245 if (urlParams.p) { 4246 this.registerParam("appParams", gadgets.json.parse(urlParams.p)); 4247 } 4248 4249 if (urlParams.ownerId) { 4250 this.registerParam("ownerId", gadgets.util.getUrlParameters().ownerId); 4251 } 4252 4253 if (urlParams.viewerId) { 4254 this.registerParam("viewerId", urlParams.viewerId); 4255 } 4256 4257 if (urlParams.perm) { 4258 var perm = gadgets.json.parse('{"permissions":' + urlParams.perm + '}'); 4259 this.registerParam("ownerPerm", perm.permissions); 4260 if (urlParams.viewerId === urlParams.ownerId) { 4261 this.registerParam("viewerPerm", perm.permissions); 4262 } 4263 else if (urlParams.viewer_perm) { 4264 perm = gadgets.json.parse('"permissions":' + urlParams.viewer_perm); 4265 this.registerParam("viewerPerm", perm.permissions); 4266 } 4267 } 4268 4269 if (urlParams.userBlockedApp || urlParams.userLoggedOut || "0" === urlParams.installState) { 4270 this.registerParam("denyViewer", true); 4271 } 4272 else { 4273 this.registerParam("denyViewer", false); 4274 } 4275 4276 if (urlParams.installState) { 4277 this.registerParam("installState", urlParams.installState); 4278 } 4279 4280 var supportedPostToTargets = ""; 4281 if (urlParams && urlParams.pto) { 4282 supportedPostToTargets = urlParams.pto.split(","); 4283 this.myspaceenvironment_ = this.newMySpaceEnvironment(supportedPostToTargets); 4284 } 4285 4286 var supportedPersonFields = {}; 4287 supportedPersonFields[opensocial.Person.Field.ABOUT_ME] = true; 4288 supportedPersonFields[opensocial.Person.Field.AGE] = true; 4289 supportedPersonFields[opensocial.Person.Field.BODY_TYPE] = true; 4290 supportedPersonFields[opensocial.Person.Field.BOOKS] = true; 4291 supportedPersonFields[opensocial.Person.Field.CHILDREN] = true; 4292 supportedPersonFields[opensocial.Person.Field.CURRENT_LOCATION] = true; 4293 supportedPersonFields[opensocial.Person.Field.DATE_OF_BIRTH] = true; 4294 supportedPersonFields[opensocial.Person.Field.DRINKER] = true; 4295 supportedPersonFields[opensocial.Person.Field.ETHNICITY] = true; 4296 supportedPersonFields[opensocial.Person.Field.GENDER] = true; 4297 supportedPersonFields[opensocial.Person.Field.HAS_APP] = true; 4298 supportedPersonFields[opensocial.Person.Field.HEROES] = true; 4299 supportedPersonFields[opensocial.Person.Field.ID] = true; 4300 supportedPersonFields[opensocial.Person.Field.INTERESTS] = true; 4301 supportedPersonFields[opensocial.Person.Field.JOBS] = true; 4302 supportedPersonFields[opensocial.Person.Field.LOOKING_FOR] = true; 4303 supportedPersonFields[opensocial.Person.Field.MOVIES] = true; 4304 supportedPersonFields[opensocial.Person.Field.MUSIC] = true; 4305 supportedPersonFields[opensocial.Person.Field.NAME] = true; 4306 supportedPersonFields[opensocial.Person.Field.NETWORK_PRESENCE] = true; 4307 supportedPersonFields[opensocial.Person.Field.NICKNAME] = true; 4308 supportedPersonFields[opensocial.Person.Field.PROFILE_SONG] = true; 4309 supportedPersonFields[opensocial.Person.Field.PROFILE_URL] = true; 4310 supportedPersonFields[opensocial.Person.Field.RELATIONSHIP_STATUS] = true; 4311 supportedPersonFields[opensocial.Person.Field.RELIGION] = true; 4312 supportedPersonFields[opensocial.Person.Field.SEXUAL_ORIENTATION] = true; 4313 supportedPersonFields[opensocial.Person.Field.SMOKER] = true; 4314 supportedPersonFields[opensocial.Person.Field.STATUS] = true; 4315 supportedPersonFields[opensocial.Person.Field.THUMBNAIL_URL] = true; 4316 supportedPersonFields[opensocial.Person.Field.TV_SHOWS] = true; 4317 supportedPersonFields[opensocial.Person.Field.URLS] = true; 4318 supportedPersonFields[MyOpenSpace.Person.Field.MEDIUM_IMAGE] = true; 4319 supportedPersonFields[MyOpenSpace.Person.Field.LARGE_IMAGE] = true; 4320 4321 var supportedFilters = {}; 4322 supportedFilters[opensocial.DataRequest.FilterType.ALL] = true; 4323 supportedFilters[opensocial.DataRequest.FilterType.HAS_APP] = true; 4324 //supportedFilters[opensocial.DataRequest.FilterType.IS_FRIENDS_WITH] = false; 4325 supportedFilters[opensocial.DataRequest.FilterType.TOP_FRIENDS] = true; 4326 //supportedFilters[MyOpenSpace.DataRequest.FilterType.ONLINE_FRIENDS] = true; 4327 4328 var supportedFields = {}; 4329 supportedFields[opensocial.Environment.ObjectType.PERSON] = supportedPersonFields; 4330 supportedFields[MyOpenSpace.Environment.ObjectType.PERSON] = supportedPersonFields; 4331 supportedFields[MyOpenSpace.Environment.ObjectType.VIDEO] = MyOpenSpace.Video.Field; 4332 supportedFields[MyOpenSpace.Environment.ObjectType.ALBUM] = MyOpenSpace.Album.Field; 4333 supportedFields[MyOpenSpace.Environment.ObjectType.PHOTO] = MyOpenSpace.Photo.Field; 4334 supportedFields[opensocial.Environment.ObjectType.FILTER_TYPE] = supportedFilters; 4335 4336 this.environment_ = this.newEnvironment("myspace.com", supportedFields); 4337 4338 this.endPoint_ = MyOpenSpace.EndPoint.Tokenized(MyOpenSpace.EndPoint, opensocial.IdSpec.PersonId, this.osToken_, this.osMode_); 4339 4340 /* Expose as property for now */ 4341 MyOpenSpace.MySpaceContainer.OSToken = this.osToken_; 4342 4343 opensocial.Container.call(this, false); 4344 opensocial.Container.setContainer(this); 4345 }; 4346 MyOpenSpace.MySpaceContainer.inherits(opensocial.Container); 4347 4348 /** 4349 * The parameters that are passed between surfaces. 4350 * @private 4351 * @private 4352 */ 4353 MyOpenSpace.MySpaceContainer.prototype.params_ = null; 4354 4355 /** 4356 * Private instance of the request processor, use MySpaceContainer.getRequestProcessor to access. 4357 * @type {MyOpenSpace.RequestProcessor_} 4358 * @private 4359 * @private 4360 */ 4361 MyOpenSpace.MySpaceContainer.prototype.requestProcessor_ = null; 4362 4363 /** 4364 * Private instance of the environment, use MySpaceContainer.getEnvironment to access. 4365 * @type {opensocial.Environment} 4366 * @private 4367 * @private 4368 */ 4369 MyOpenSpace.MySpaceContainer.prototype.environment_ = null; 4370 4371 /** 4372 * Private instance of the MySpace environment, use MySpaceContainer.getMySpaceEnvironment to access. 4373 * @type {MyOpenSpace.Environment} 4374 * @private 4375 * @private 4376 */ 4377 MyOpenSpace.MySpaceContainer.prototype.myspaceenvironment_ = null; 4378 4379 /** 4380 * Returns the container's MySpace environment object 4381 * @return {MyOpenSpace.Environment} 4382 */ 4383 MyOpenSpace.MySpaceContainer.prototype.getMySpaceEnvironment = function() { return this.myspaceenvironment_; }; 4384 4385 /** 4386 * Returns the container's request processor 4387 * @return {MyOpenSpace.RequestProcessor_} 4388 * @private 4389 */ 4390 MyOpenSpace.MySpaceContainer.prototype.getRequestProcessor = function() { return this.requestProcessor_; }; 4391 4392 /** 4393 * Returns the container's environment object. 4394 * @return {opensocial.Environment} 4395 * @private 4396 */ 4397 MyOpenSpace.MySpaceContainer.prototype.getEnvironment = function() { return this.environment_; }; 4398 4399 /** 4400 * Returns a new MyOpenSpace.Person instance 4401 * @param {Map<opensocial.DataRequest.PeopleRequestFields>} opt_params Optional parameters specified when creating the person. 4402 * @param {Boolean} opt_isViewer True if this is the viewer of the page otherwise, false. 4403 * @param {Boolean} opt_isOwner True if this is the owner of the page otherwise, false. 4404 * @return {MyOpenSpace.Person} The person object 4405 * @private 4406 */ 4407 MyOpenSpace.MySpaceContainer.prototype.newPerson = function(opt_params, opt_isOwner, opt_isViewer){ 4408 return new MyOpenSpace.Person(opt_params, opt_isOwner, opt_isViewer); 4409 }; 4410 4411 MyOpenSpace.MySpaceContainer.prototype.newName = function(opt_params){ 4412 return new opensocial.Name(opt_params); 4413 }; 4414 4415 4416 /** 4417 * Returns a new MyOpenSpace.Album instance 4418 * @param {undefined} opt_params Unused at this time. 4419 * @return {MyOpenSpace.Album} The album object 4420 */ 4421 MyOpenSpace.MySpaceContainer.prototype.newAlbum = function(opt_params){ 4422 return new MyOpenSpace.Album(opt_params); 4423 }; 4424 4425 /** 4426 * Returns a new MyOpenSpace.Indicators instance 4427 * @param {undefined} opt_params Unused at this time. 4428 * @return {MyOpenSpace.Indicators} The indicators object 4429 */ 4430 MyOpenSpace.MySpaceContainer.prototype.newIndicators = function(opt_params){ 4431 return new MyOpenSpace.Indicators(opt_params); 4432 }; 4433 /** 4434 * Returns a new MyOpenSpace.PersonStatus instance 4435 * @param {undefined} opt_params Unused at this time. 4436 * @return {MyOpenSpace.PersonStatus} The PersonStatus object 4437 */ 4438 MyOpenSpace.MySpaceContainer.prototype.newPersonStatus = function(opt_params){ 4439 return new MyOpenSpace.PersonStatus(opt_params); 4440 }; 4441 /** 4442 * Returns a new MyOpenSpace.PersonMood instance 4443 * @param {undefined} opt_params Unused at this time. 4444 * @return {MyOpenSpace.PersonStatus} The PersonMood object 4445 */ 4446 MyOpenSpace.MySpaceContainer.prototype.newPersonMood = function(opt_params){ 4447 return new MyOpenSpace.PersonMood(opt_params); 4448 }; 4449 /** 4450 * Returns a new MyOpenSpace.Friendship instance 4451 * @param {undefined} opt_params Unused at this time. 4452 * @return {MyOpenSpace.Friendship} The Friendship object 4453 */ 4454 MyOpenSpace.MySpaceContainer.prototype.newFriendship = function(opt_params){ 4455 return new MyOpenSpace.Friendship(opt_params); 4456 }; 4457 4458 /** 4459 * Returns a new MyOpenSpace.Video instance 4460 * @param {undefined} opt_params Unused at this time. 4461 * @return {MyOpenSpace.Video} The album object 4462 */ 4463 MyOpenSpace.MySpaceContainer.prototype.newVideo = function(opt_params){ 4464 return new MyOpenSpace.Video(opt_params); 4465 }; 4466 4467 4468 /** 4469 * Returns a new MyOpenSpace.Photo instance 4470 * @param {undefined} opt_params Unused at this time. 4471 * @return {MyOpenSpace.Photo} The photo object 4472 */ 4473 MyOpenSpace.MySpaceContainer.prototype.newPhoto = function(opt_params){ 4474 return new MyOpenSpace.Photo(opt_params); 4475 }; 4476 4477 /** 4478 * Returns a new opensocial.DataRequest instance, which is overridden locally 4479 * @function 4480 * @return {opensocial.DataRequest} The data request object 4481 * @private 4482 */ 4483 MyOpenSpace.MySpaceContainer.prototype.newDataRequest = function(){ 4484 return new MyOpenSpace.DataRequest(this.osToken_, this.endPoint_); 4485 }; 4486 4487 /** 4488 * Returns a new opensocial.ResponseItem instance 4489 * @function 4490 * @param {opensocial.DataRequest} originalDataRequest The ID of the photo to fetch 4491 * @param {Object || null} data The object retrieved, can be any entity, or null if nothing was found. 4492 * @param {String} opt_errorCode A code defining the error that occurred, if any. 4493 * @param {String} opt_errorMessage A message detailing the error that occurred, if any. 4494 * @return {opensocial.ResponseItem} The response item object 4495 * @private 4496 */ 4497 MyOpenSpace.MySpaceContainer.prototype.newResponseItem = function(originalDataRequest, data, opt_errorCode, opt_errorMessage) { 4498 return new opensocial.ResponseItem(originalDataRequest, data, opt_errorCode, opt_errorMessage); 4499 }; 4500 4501 /** 4502 * Creates an object to be used when sending to the server. 4503 * @param {String} id The ID (VIEWER or OWNER) of the person. 4504 * @param {undefined} opt_params Not used at this time. 4505 * @return {Object} A request object. 4506 * @private 4507 */ 4508 MyOpenSpace.MySpaceContainer.prototype.newFetchPersonRequest = function(id, opt_params) { 4509 opt_params = opt_params || {}; 4510 return { 4511 type: MyOpenSpace.RequestType.FETCH_PERSON, 4512 parameters: { 4513 id:id, 4514 profileDetail: this.mapPersonDetails_(opt_params), 4515 useCache: (opt_params[MyOpenSpace.DataRequest.CacheControl.USE_CACHE] || true), 4516 refreshInterval: (opt_params[MyOpenSpace.DataRequest.CacheControl.REFRESH_INTERVAL] || 0) 4517 } 4518 }; 4519 }; 4520 4521 /** 4522 * Creates an object to be used when sending to the server. 4523 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the photo 4524 * @param {Number} photo_id The ID of the photo to fetch 4525 * @param {undefined} opt_params Not used at this time. 4526 * @return {Object} A request object 4527 * @private 4528 */ 4529 MyOpenSpace.MySpaceContainer.prototype.newFetchPhotoRequest = function(id, photo_id, opt_params){ 4530 return { 4531 type: MyOpenSpace.RequestType.FETCH_PHOTO, 4532 parameters: { 4533 id:id, 4534 photo_id:photo_id 4535 } 4536 }; 4537 }; 4538 4539 /** 4540 * Creates an object to be used when sending to the server 4541 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the photos 4542 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the photos. 4543 * @return {Object} A request object 4544 * @private 4545 */ 4546 MyOpenSpace.MySpaceContainer.prototype.newFetchPhotosRequest = function(id, opt_params){ 4547 opt_params = opt_params || {}; 4548 return { 4549 type: MyOpenSpace.RequestType.FETCH_PHOTOS, 4550 parameters: { 4551 id:id, 4552 album_id: opt_params[MyOpenSpace.DataRequest.PhotoRequestFields.ALBUM_ID] || null, 4553 first: opt_params[opensocial.DataRequest.PeopleRequestFields.FIRST] || 1, 4554 max: opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] || MyOpenSpace.DefaultPageSize 4555 } 4556 }; 4557 }; 4558 4559 /** 4560 * Creates an object to be used when sending to the server 4561 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the album 4562 * @param {Number} album_id The ID of the photo to fetch 4563 * @param {undefined} opt_params Not used at this time. 4564 * @return {Object} A request object 4565 * @private 4566 */ 4567 MyOpenSpace.MySpaceContainer.prototype.newFetchAlbumRequest = function(id, album_id, opt_params){ 4568 return { 4569 type: MyOpenSpace.RequestType.FETCH_ALBUM, 4570 parameters: { 4571 id:id, 4572 album_id:album_id 4573 } 4574 }; 4575 }; 4576 4577 /** 4578 * Creates an object to be used when sending to the server 4579 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the albums 4580 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the albums. 4581 * @return {Object} A request object 4582 * @private 4583 */ 4584 MyOpenSpace.MySpaceContainer.prototype.newFetchAlbumsRequest = function(id, opt_params){ 4585 opt_params = opt_params || {}; 4586 return { 4587 type: MyOpenSpace.RequestType.FETCH_ALBUMS, 4588 parameters: { 4589 id:id, 4590 first: opt_params[opensocial.DataRequest.PeopleRequestFields.FIRST] || 1, 4591 max: opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] || MyOpenSpace.DefaultPageSize 4592 } 4593 }; 4594 }; 4595 4596 /** 4597 * Creates an object to be used when sending to the server 4598 * @param {String} id The ID (VIEWER or OWNER) of the person who owns the album 4599 * @param {Number} video_id The ID of the photo to fetch 4600 * @param {undefined} opt_params Not used at this time. 4601 * @return {Object} A request object 4602 * @private 4603 */ 4604 MyOpenSpace.MySpaceContainer.prototype.newFetchVideoRequest = function(id, video_id, opt_params){ 4605 return { 4606 type: MyOpenSpace.RequestType.FETCH_VIDEO, 4607 parameters: { 4608 id:id, 4609 video_id:video_id 4610 } 4611 }; 4612 }; 4613 4614 /** 4615 * Creates an object to be used when sending to the server 4616 * @param {String} id The ID (VIEWER or OWNER) of the person. 4617 * @param {Map<opensocial.DataRequest.PeopleRequestFields.FIRST || opensocial.DataRequest.PeopleRequestFields.MAX>} opt_params Optional parameters specified when creating the videos. 4618 * @return {Object} A request object 4619 * @private 4620 */ 4621 MyOpenSpace.MySpaceContainer.prototype.newFetchVideosRequest = function(id, opt_params){ 4622 opt_params = opt_params || {}; 4623 return { 4624 type: MyOpenSpace.RequestType.FETCH_VIDEOS, 4625 parameters: { 4626 id:id, 4627 first: opt_params[opensocial.DataRequest.PeopleRequestFields.FIRST] || 1, 4628 max: opt_params[opensocial.DataRequest.PeopleRequestFields.MAX] || MyOpenSpace.DefaultPageSize 4629 } 4630 }; 4631 }; 4632 4633 /** 4634 * Creates an object to be used when sending to the server. 4635 * @param {String} id The ID (VIEWER or OWNER) of the person. 4636 * @param {undefined} opt_params Not used at this time. 4637 * @return {Object} A request object. 4638 * @private 4639 */ 4640 MyOpenSpace.MySpaceContainer.prototype.newFetchIndicatorsRequest = function(id, opt_parms){ 4641 return { 4642 type: MyOpenSpace.RequestType.FETCH_INDICATORS, 4643 parameters: { 4644 id: id 4645 } 4646 }; 4647 }; 4648 4649 /** 4650 * Creates an object to be used when sending to the server. 4651 * @param {String} id The ID (VIEWER or OWNER) of the person. 4652 * @param {undefined} opt_params Not used at this time. 4653 * @return {Object} A request object. 4654 * @private 4655 */ 4656 MyOpenSpace.MySpaceContainer.prototype.newFetchPersonStatusRequest = function(id, opt_parms){ 4657 return { 4658 type: MyOpenSpace.RequestType.FETCH_PERSON_STATUS, 4659 parameters: { 4660 id: id 4661 } 4662 }; 4663 }; 4664 4665 /** 4666 * Creates an object to be used when sending to the server. 4667 * @param {String} id The ID (VIEWER or OWNER) of the person. 4668 * @param {undefined} opt_params Not used at this time. 4669 * @return {Object} A request object. 4670 * @private 4671 */ 4672 MyOpenSpace.MySpaceContainer.prototype.newFetchPersonMoodRequest = function(id, opt_parms){ 4673 return { 4674 type: MyOpenSpace.RequestType.FETCH_PERSON_MOOD, 4675 parameters: { 4676 id: id 4677 } 4678 }; 4679 }; 4680 4681 /** 4682 * Creates an object to be used when sending to the server. 4683 * @param {String} id The ID (VIEWER or OWNER) of the person. 4684 * @param {String} person id. 4685 * @param {undefined} opt_params Not used at this time. 4686 * @return {Object} A request object. 4687 * @private 4688 */ 4689 MyOpenSpace.MySpaceContainer.prototype.newFetchPersonFriendshipRequest = function(id, key, opt_parms){ 4690 return { 4691 type: MyOpenSpace.RequestType.FETCH_PERSON_FRIENDSHIP, 4692 parameters: { 4693 id: id, 4694 key: key 4695 } 4696 }; 4697 }; 4698 4699 /** 4700 * Creates an object to be used when sending to the server. 4701 * @param {String} id The ID (VIEWER or OWNER) of the person. 4702 * @param {Array} array of person ids. 4703 * @param {undefined} opt_params Not used at this time. 4704 * @return {Object} A request object. 4705 * @private 4706 */ 4707 MyOpenSpace.MySpaceContainer.prototype.newFetchPeopleFriendshipRequest = function(id, key, opt_parms){ 4708 return { 4709 type: MyOpenSpace.RequestType.FETCH_PEOPLE_FRIENDSHIP, 4710 parameters: { 4711 id: id, 4712 key: key 4713 } 4714 }; 4715 }; 4716 4717 /** 4718 * Creates an item to request friends from the server. 4719 * When processed, returns an opensocial.Collection<MyOpenSpace.Person> object. 4720 * @param {Array.<String> | String} idSpec An ID reference used to specify which people to fetch; the supported keys VIEWER_FRIENDS or OWNER_FRIENDS. 4721 * @param {Map.<opensocial.DataRequest.PeopleRequestFields} opt_params Additional opensocial.DataRequest.PeopleRequestFields params to pass to the request. 4722 * @return {Object} A request object. 4723 * @private 4724 */ 4725 MyOpenSpace.MySpaceContainer.prototype.newFetchPeopleRequest = function(idSpec, opt_params) { 4726 opt_params = opt_params || {}; 4727 var fields = opensocial.DataRequest.PeopleRequestFields; 4728 var groups = opensocial.DataRequest.Group; 4729 var type = MyOpenSpace.RequestType.FETCH_PEOPLE; 4730 4731 return { 4732 type: type, 4733 parameters: { 4734 idSpec:idSpec, 4735 sortOrder:opt_params[fields.SORT_ORDER], 4736 details:opt_params[fields.PROFILE_DETAILS], 4737 filter:opt_params[fields.FILTER] || opensocial.DataRequest.FilterType.ALL, 4738 first:opt_params[fields.FIRST] || 1, 4739 max:opt_params[fields.MAX] || MyOpenSpace.DefaultPageSize 4740 } 4741 }; 4742 }; 4743 4744 /** 4745 * Determines if the requested Person will be mapped internally to BASIC, FULL or EXTENDED 4746 * @function 4747 * @return {MyOpenSpace.DetailType} The detail type of the requested person 4748 * @private 4749 * @private 4750 */ 4751 MyOpenSpace.MySpaceContainer.prototype.mapPersonDetails_ = function(params) { 4752 var details = params && params[opensocial.DataRequest.PeopleRequestFields.PROFILE_DETAILS]; 4753 if(!details) return {fields:"id,name,familyName,givenName,nickname,thumbnailUrl,profileUrl",unsupported:null}; 4754 4755 var fields =[]; 4756 var unsupported =[]; 4757 4758 fields[opensocial.Person.Field.ID] = opensocial.Person.Field.ID; 4759 fields[opensocial.Person.Field.NAME] = 'name,familyName,givenName'; 4760 fields[opensocial.Person.Field.NICKNAME] = opensocial.Person.Field.NICKNAME; 4761 fields[opensocial.Person.Field.THUMBNAIL_URL] = opensocial.Person.Field.THUMBNAIL_URL; 4762 fields[opensocial.Person.Field.PROFILE_URL] = opensocial.Person.Field.PROFILE_URL; 4763 4764 var environment = opensocial.getEnvironment(); 4765 4766 for(var i = 0; i < details.length; i++){ 4767 switch (details[i]){ 4768 case opensocial.Person.Field.NAME: 4769 fields[opensocial.Person.Field.NAME] = 'name,familyName,givenName'; 4770 break; 4771 case opensocial.Person.Field.JOBS: 4772 fields[opensocial.Person.Field.JOBS] = 'organizations'; 4773 break; 4774 case MyOpenSpace.Person.Field.LARGE_IMAGE: 4775 case MyOpenSpace.Person.Field.MEDIUM_IMAGE: 4776 fields['photos'] = 'photos'; 4777 break; 4778 default: 4779 if (environment.supportsField(opensocial.Environment.ObjectType.PERSON, details[i])){ 4780 fields[details[i]] = details[i]; 4781 } 4782 else{ 4783 unsupported[details[i]] = true; 4784 } 4785 break; 4786 } 4787 } 4788 4789 unsupportedStr = ''; 4790 for (var i in unsupported) unsupportedStr += i + ', '; 4791 if (unsupportedStr === '') { 4792 unsupportedStr = null; 4793 } 4794 else { 4795 unsupportedStr = unsupportedStr.substr(0, unsupportedStr.length - 2); 4796 } 4797 4798 4799 var fieldsStr = ''; 4800 for (var i in fields) fieldsStr += fields[i] + ','; 4801 fieldsStr = fieldsStr.substr(0, fieldsStr.length - 1); 4802 return {fields:fieldsStr,unsupported:unsupportedStr}; 4803 }; 4804 4805 4806 4807 /** 4808 * Get a new MySpace environment object. 4809 * @return {MyOpenSpace.Environment} the MySpace environment object 4810 * @private 4811 */ 4812 MyOpenSpace.MySpaceContainer.prototype.newMySpaceEnvironment = function(supportedPostToTargets, app) { 4813 return new MyOpenSpace.Environment(supportedPostToTargets, app); 4814 }; 4815 4816 /** 4817 * Starts the sending process 4818 * @param {opensocial.DataRequest} dataRequest The request to get processed and sent 4819 * @private 4820 */ 4821 MyOpenSpace.MySpaceContainer.prototype.requestData = function(dataRequest, callback) { 4822 dataRequest.requestProcessor_.prepareForSend(dataRequest); 4823 dataRequest.requestProcessor_.startProcessing(); 4824 }; 4825 4826 MyOpenSpace.MySpaceContainer.prototype.enableCaja = function() { 4827 opensocial.Container.prototype.enableCaja(); 4828 4829 ___.allowCall(MyOpenSpace.Album.prototype, 'getField'); 4830 ___.allowCall(MyOpenSpace.Album.prototype, 'setField_'); 4831 4832 ___.allowCall(MyOpenSpace.Video.prototype, 'getField'); 4833 ___.allowCall(MyOpenSpace.Video.prototype, 'setField_'); 4834 4835 ___.allowCall(MyOpenSpace.Photo.prototype, 'getField'); 4836 ___.allowCall(MyOpenSpace.Photo.prototype, 'setField_'); 4837 }; 4838 4839 /** 4840 * Kicks off the request processor 4841 * @private 4842 * @private 4843 */ 4844 MyOpenSpace.MySpaceContainer.prototype.startProcessor_ = function(){ //TODO: rework how we are unspooling requestactions?? 4845 //if (this.requestProcessor_._readyToSend) 4846 //this.requestProcessor_.startProcessing(); 4847 }; 4848 4849 MyOpenSpace.MySpaceContainer.prototype.newFetchGlobalAppDataRequest = function() { 4850 return { 4851 type: MyOpenSpace.RequestType.FETCH_GLOBAL_DATA 4852 }; 4853 }; 4854 4855 MyOpenSpace.MySpaceContainer.prototype.newFetchInstanceAppDataRequest = function() { 4856 return { 4857 type: MyOpenSpace.RequestType.FETCH_INSTANCE_DATA 4858 }; 4859 }; 4860 4861 MyOpenSpace.MySpaceContainer.prototype.newUpdateInstanceAppDataRequest = function() { 4862 return { 4863 type: MyOpenSpace.RequestType.UPDATE_INSTANCE_DATA 4864 }; 4865 }; 4866 4867 MyOpenSpace.MySpaceContainer.prototype.newFetchPersonAppDataRequest = function(idSpec, keys, opt_params) { 4868 return { 4869 type: MyOpenSpace.RequestType.FETCH_PERSON_DATA, 4870 parameters : { 4871 idSpec: idSpec, 4872 keys: keys, 4873 opt_params: opt_params 4874 } 4875 }; 4876 }; 4877 4878 MyOpenSpace.MySpaceContainer.prototype.newUpdatePersonAppDataRequest = function(id, key, value) { 4879 return { 4880 type: MyOpenSpace.RequestType.UPDATE_PERSON_DATA, 4881 parameters : { 4882 id: id, 4883 key : key, 4884 value : value 4885 } 4886 }; 4887 }; 4888 4889 MyOpenSpace.MySpaceContainer.prototype.newRemovePersonAppDataRequest = function(id, keys) { 4890 return { 4891 type: MyOpenSpace.RequestType.REMOVE_PERSON_DATA, 4892 parameters : { 4893 id: id, 4894 keys: keys 4895 } 4896 }; 4897 }; 4898 4899 MyOpenSpace.MySpaceContainer.prototype.newFetchActivitiesRequest = function(idSpec, opt_params) { 4900 return { 4901 type: MyOpenSpace.RequestType.FETCH_ACTIVITIES, 4902 parameters : { 4903 idSpec: idSpec 4904 } 4905 }; 4906 } ; 4907 4908 MyOpenSpace.MySpaceContainer.prototype.requestCreateActivity = function(activity, priority, opt_callback) { 4909 var goodResult = function(response) { 4910 var callbackWithError = function(errorCode, errorMessage) { 4911 opt_callback(opensocial.Container.get().newResponseItem(null, null, errorCode, errorMessage)); 4912 }; 4913 4914 if (response) { 4915 try{ 4916 response = eval("(" + response.responseText + ")"); 4917 } 4918 catch (err) { 4919 callbackWithError(opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error parsing response."); 4920 return; 4921 } 4922 4923 if(response && "posted" === response.postactivitystatus){ 4924 opt_callback(opensocial.Container.get().newResponseItem(null, response, "", "")); 4925 return; 4926 } 4927 } 4928 callbackWithError(opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error parsing response."); 4929 }; 4930 var badResult = function(response) { 4931 opt_callback(opensocial.Container.get().newResponseItem(null, null, response.errorCode, response.errorMessage)); 4932 }; 4933 4934 if (!activity.getField(opensocial.Activity.Field.TITLE_ID)) { 4935 var ri = opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.BAD_REQUEST, "You must supply a TITLE_ID."); 4936 opt_callback(ri); 4937 return; 4938 } 4939 4940 var dataRequestAction = {}; 4941 dataRequestAction.method = "POST"; 4942 dataRequestAction.endPoint = this.endPoint_.Activities.ViewerInsert; 4943 dataRequestAction.params = "templateId="; 4944 dataRequestAction.params += escape(activity.getField(opensocial.Activity.Field.TITLE_ID)); 4945 4946 if (activity.getField(opensocial.Activity.Field.TEMPLATE_PARAMS)) { 4947 dataRequestAction.params += "&templateParameters="; 4948 dataRequestAction.params += escape(gadgets.json.stringify(activity.getField(opensocial.Activity.Field.TEMPLATE_PARAMS))); 4949 } 4950 4951 if (activity.getField(opensocial.Activity.Field.MEDIA_ITEMS)) { 4952 dataRequestAction.params += "&mediaItems="; 4953 var mediaItemsOld = activity.getField(opensocial.Activity.Field.MEDIA_ITEMS); 4954 var mediaItemsNew = "{"; 4955 4956 for (var i = 0; i < mediaItemsOld.length; i++) { 4957 if (0 !== i) { 4958 mediaItemsNew += ","; 4959 } 4960 mediaItemsNew += "\"" + mediaItemsOld[i].getField(opensocial.MediaItem.Field.URL) + "\""; 4961 } 4962 mediaItemsNew += "}"; 4963 4964 dataRequestAction.params += escape(mediaItemsNew); 4965 } 4966 4967 dataRequestAction.osToken_ = this.osToken_; 4968 MyOpenSpace.Ajax.sendRequest(dataRequestAction, "INSERT_ACTIVITIES-VIEWER", goodResult, badResult, true, null); 4969 }; 4970 4971 /** 4972 * TODO: comment this once finalized 4973 * IFPC support inside container 4974 * @private 4975 */ 4976 var _IFPC = window["_IFPC"]; 4977 MyOpenSpace.MySpaceContainer.prototype.registerParam = function(key, value) { 4978 4979 /*if("appParams" === key){ 4980 // unspool the opt_key params and put them in the base params_ list with the others. 4981 for(var i in value){ 4982 this.params_[i] = value[i]; 4983 gadgets.views.getParams()[i] = value[i]; 4984 } 4985 } 4986 else*/ if("ptoString" === key){ 4987 opensocial.Container.get().myspaceenvironment_ = this.newMySpaceEnvironment(value.split(",")); 4988 } 4989 else{ 4990 this.params_[key] = value; 4991 gadgets.views.getParams()[key] = value; 4992 //if("appid" === key){ 4993 //this.prefs.parseUrl(value); 4994 //} 4995 } 4996 }; 4997 4998 MyOpenSpace.MySpaceContainer.prototype.requestPermission = function(permissions, reason, opt_callback){ 4999 var supportedPermissions = [ 5000 MyOpenSpace.Permission.VIEWER_DISPLAY_ON_PROFILE, 5001 MyOpenSpace.Permission.VIEWER_DISPLAY_ON_HOME, 5002 MyOpenSpace.Permission.VIEWER_SEND_UPDATES_TO_FRIENDS, 5003 MyOpenSpace.Permission.VIEWER_ACCESS_TO_PRIVATE_VIDEOS_PHOTOS, 5004 MyOpenSpace.Permission.VIEWER_ACCESS_TO_PUBLIC_VIDEOS_PHOTOS, 5005 MyOpenSpace.Permission.VIEWER_SHOW_UPDATES_FROM_FRIENDS 5006 ]; 5007 5008 if(gadgets.views.ViewType.CANVAS === gadgets.views.getCurrentView().getName()){ 5009 var validatedPermissions = new Array(); 5010 if(permissions && permissions instanceof Array) { 5011 for(i=0;i<permissions.length;i++) { 5012 //Check that is a valid permission object 5013 if (typeof(permissions[i].user) !== 'undefined' && 5014 typeof(permissions[i].permission) !== 'undefined'){ 5015 //Check if the permission is supported 5016 for (var supported in supportedPermissions){ 5017 if (supportedPermissions[supported].user === permissions[i].user && 5018 supportedPermissions[supported].permission === permissions[i].permission){ 5019 //check if the user doesn't have the requested permission. 5020 if (!this.hasPermission(permissions[i])){ 5021 validatedPermissions.push(permissions[i].permission); 5022 } 5023 break; 5024 } 5025 } 5026 5027 } 5028 } 5029 } 5030 5031 var userGrantedPermissions_sync = function (permissionState){ 5032 if(permissionState){ 5033 var currentContainer = opensocial.Container.get(); 5034 var currentPermissions = gadgets.views.getParams().viewerPerm; 5035 var permissionsGranted = []; 5036 for(var key in permissionState){ 5037 var permObj = null; 5038 var granted = permissionState[key]; 5039 for (var permIdex in supportedPermissions){ 5040 if (supportedPermissions[permIdex].permission.toLowerCase() === key.toLowerCase()){ 5041 permObj = supportedPermissions[permIdex]; 5042 break; 5043 } 5044 } 5045 if (permObj !== null){ 5046 if (granted) { 5047 permissionsGranted.push(permObj); 5048 } 5049 var permissionExist = false; 5050 var permissionIndex = 0; 5051 //Add permission to viewerPerm if is not there 5052 for (var permIndex in currentPermissions){ 5053 if (currentPermissions[permIdex] === permObj.permissionIndicator){ 5054 permissionExist = true; 5055 permissionIndex = permIndex; 5056 break; 5057 } 5058 } 5059 if (!permissionExist && granted) { 5060 currentPermissions.push(permObj.permissionIndicator); 5061 currentContainer.registerParam("viewerPerm", currentPermissions); 5062 } 5063 else if (permissionExist && !granted){ 5064 currentPermissions.splice(permissionIndex, 1); 5065 currentContainer.registerParam("viewerPerm", currentPermissions); 5066 } 5067 } 5068 } 5069 if (opt_callback) { 5070 if (permissionsGranted.length > 0) { 5071 opt_callback(opensocial.Container.get().newResponseItem(null, permissionsGranted, "", "")); 5072 } 5073 else { 5074 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "No new permissions were granted.")); 5075 } 5076 return; 5077 } 5078 } 5079 else{ 5080 if(opt_callback) opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "No new permissions were granted.")); 5081 return; 5082 } 5083 }; 5084 5085 if (validatedPermissions.length === 0) { 5086 if(opt_callback) opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "No new permissions were granted.")); 5087 return; 5088 } 5089 _IFPC.call(this.params_.panelId, 5090 "requestPermission", 5091 [this.params_.appid, validatedPermissions, reason], 5092 this.params_.remoteRelay, 5093 userGrantedPermissions_sync, 5094 this.params_.localRelay, 5095 null); 5096 } 5097 }; 5098 5099 5100 5101 MyOpenSpace.MySpaceContainer.prototype.requestSendMessage = function(recipients, message, opt_callback, opt_params){ 5102 //Only can run on canvas 5103 if (gadgets.views.ViewType.CANVAS !== gadgets.views.getCurrentView().getName()) { 5104 if (opt_callback) { 5105 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "requestSendMessage does not support this view, only the canvas view is supported.")); 5106 } 5107 return; 5108 } 5109 5110 var target_is_supported = false; 5111 var supported = opensocial.Container.get().getMySpaceEnvironment().getSupportedPostToTargets(); 5112 var messageType = message.getField(opensocial.Message.Field.TYPE); 5113 for (var i = 0; i < supported.length; i++) { 5114 if (supported[i] === messageType) { 5115 target_is_supported = true; 5116 break; 5117 } 5118 } 5119 5120 if (!target_is_supported || messageType == MyOpenSpace.PostTo.Targets.SHARE_APP) { 5121 if (opt_callback) { 5122 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "MessageType is not supported.")); 5123 } 5124 return; 5125 } 5126 5127 if(opt_params){ 5128 if(opt_params[opensocial.NavigationParameters.DestinationType.RECIPIENT_DESTINATION]){ 5129 if (opt_callback) { 5130 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "opensocial.NavigationParameters.DestinationType.RECIPIENT_DESTINATION is not supported.")); 5131 } 5132 return; 5133 } 5134 else if (opt_params[opensocial.NavigationParameters.DestinationType.VIEWER_DESTINATION]) { 5135 if (opt_callback) { 5136 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "opensocial.NavigationParameters.DestinationType.VIEWER_DESTINATION is not supported.")); 5137 } 5138 return; 5139 } 5140 } 5141 5142 5143 if(recipients.constructor === Array){ 5144 if (opt_callback) { 5145 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "Unsupported idSpec, only VIEWER, OWNER or one friend ID is allowed.")); 5146 } 5147 return; 5148 } 5149 if (recipients !== opensocial.IdSpec.PersonId.VIEWER && recipients !== opensocial.IdSpec.PersonId.OWNER) { 5150 var results = ("" + recipients).match(/^(?:myspace\.com:)?(\d+)$/); 5151 if (results === null || results.length === 0) { 5152 if (opt_callback) { 5153 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.BAD_REQUEST, "Unsupported idSpec, only VIEWER, OWNER or one friend ID is allowed.")); 5154 } 5155 return; 5156 } 5157 } 5158 5159 var request = opensocial.newDataRequest(); 5160 request.add(request.newFetchPersonRequest(recipients)); 5161 request.message = message; 5162 request.opt_callback = opt_callback; 5163 request.send(opensocial.Container.get().requestSendMessageWrapper); 5164 }; 5165 5166 MyOpenSpace.MySpaceContainer.prototype.requestShareApp = function(recipients, reason, opt_callback, opt_params) { 5167 if (gadgets.views.ViewType.CANVAS !== gadgets.views.getCurrentView().getName()) { 5168 if (opt_callback) { 5169 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "requestShareApp does not support this view, only the canvas view is supported.")); 5170 } 5171 return; 5172 } 5173 if (opt_params) { 5174 if (opt_params[opensocial.NavigationParameters.DestinationType.RECIPIENT_DESTINATION]) { 5175 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "opensocial.NavigationParameters.DestinationType.RECIPIENT_DESTINATION is not supported.")); 5176 return; 5177 } 5178 else if (opt_params[opensocial.NavigationParameters.DestinationType.VIEWER_DESTINATION]) { 5179 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "opensocial.NavigationParameters.DestinationType.VIEWER_DESTINATION is not supported.")); 5180 return; 5181 } 5182 } 5183 5184 if (recipients.constructor === Array){ 5185 if (opt_params) { 5186 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.NOT_IMPLEMENTED, "Unsupported id, only one friend ID is allowed.")); 5187 } 5188 return; 5189 } 5190 var results = ('' + recipients).match(/^(?:myspace\.com:)?(\d+)$/); 5191 if (results === null || results.length === 0) { 5192 if (opt_params) { 5193 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.BAD_REQUEST, "Invalid id.")); 5194 } 5195 return; 5196 } 5197 5198 var request = opensocial.newDataRequest(); 5199 request.add(request.newFetchPersonRequest(results[1])); 5200 reason.setField(opensocial.Message.Field.TYPE, MyOpenSpace.PostTo.Targets.SHARE_APP); 5201 request.message = reason; 5202 request.opt_callback = opt_callback; 5203 request.send(opensocial.Container.get().requestSendMessageWrapper); 5204 5205 }; 5206 5207 MyOpenSpace.MySpaceContainer.prototype.requestSendMessageWrapper = function(response){ 5208 5209 var responseItem = response.get(MyOpenSpace.RequestType.FETCH_PERSON); 5210 var originalRequest = responseItem.getOriginalDataRequest(); 5211 var opt_callback = originalRequest.opt_callback; 5212 if (response.hadError()) { 5213 if (opt_callback) { 5214 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error requesting person object. " + responseItem.getErrorMessage())); 5215 } 5216 return; 5217 } 5218 var person = responseItem.getData(); 5219 var message = originalRequest.message; 5220 5221 opensocial.Container.get().requestSendMessageWrapperEx("", message, person, opt_callback); 5222 }; 5223 5224 /** 5225 * Takes some content from the app and sends it up to the site to be posted. 5226 * @param {String} os_token The token, this gets passed up so we can verify who's sending the request. 5227 * @param {opensocial.Message} message The content to be posted, the message type refers to the target of the post. 5228 * @param {opensocial.Person} opt_person An optional opensocial.Person object, used when a recipient is required, e.g. when posting a comment, this person will get the comment. 5229 * @param {Function} opt_callback Callback function, right now just for success/fail. 5230 * @private 5231 */ 5232 MyOpenSpace.MySpaceContainer.prototype.requestSendMessageWrapperEx = function(os_token, message, opt_person, opt_callback) { 5233 5234 5235 var messageSubject = "", messageBody, messageType = MyOpenSpace.PostTo.Targets.PROFILE; 5236 if (null !== message && "undefined" !== typeof (message)) { 5237 messageSubject = message.getField(opensocial.Message.Field.TITLE); 5238 messageBody = message.getField(opensocial.Message.Field.BODY); 5239 messageType = message.getField(opensocial.Message.Field.TYPE); 5240 } 5241 else { 5242 if (opt_callback) { 5243 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.BAD_REQUEST, "You must supply a valid opensocial.Message object.")); 5244 } 5245 return; 5246 } 5247 5248 // subject and type are optional params for opensocial.newMessage, so define defaults here, i just randomly picked profile. 5249 var personId, personName, personImage, personProfile; 5250 if (null !== opt_person && "undefined" !== typeof (opt_person)) { 5251 personId = opt_person.getId(); 5252 personId = ('' + personId).match(/^(?:myspace\.com:)?(\d+)$/)[1]; 5253 personName = opt_person.getDisplayName(); 5254 personImage = opt_person.getField(opensocial.Person.Field.THUMBNAIL_URL); 5255 personProfile = opt_person.getField(opensocial.Person.Field.PROFILE_URL); 5256 } 5257 5258 var mappedMessageType; 5259 switch (messageType) { 5260 case opensocial.Message.Type.PRIVATE_MESSAGE: 5261 mappedMessageType = MyOpenSpace.PostTo.Targets.SEND_MESSAGE; 5262 break; 5263 case opensocial.Message.Type.NOTIFICATION: 5264 mappedMessageType = MyOpenSpace.PostTo.Targets.BULLETINS; 5265 break; 5266 case opensocial.Message.Type.PUBLIC_MESSAGE: 5267 mappedMessageType = MyOpenSpace.PostTo.Targets.COMMENTS; 5268 break; 5269 default: 5270 mappedMessageType = messageType; 5271 break; 5272 } 5273 5274 var messageSend_sync = function (postToResults){ 5275 if (typeof(postToResults) === 'undefined') { 5276 if (opt_callback) { 5277 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error sending request.")); 5278 } 5279 return; 5280 } 5281 5282 if (opt_callback) { 5283 switch (postToResults){ 5284 case MyOpenSpace.PostTo.Result.ERROR: 5285 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error sending request.")); 5286 break; 5287 case MyOpenSpace.PostTo.Result.CANCELLED: 5288 case MyOpenSpace.PostTo.Result.SUCCESS: 5289 opt_callback(opensocial.Container.get().newResponseItem(null, postToResults, "", "")); 5290 break; 5291 default: 5292 opt_callback(opensocial.Container.get().newResponseItem(null, null, opensocial.ResponseItem.Error.INTERNAL_ERROR, "Error sending request.")); 5293 } 5294 } 5295 5296 }; 5297 5298 5299 _IFPC.call( 5300 this.params_.panelId, 5301 "postTo", 5302 [MyOpenSpace.MySpaceContainer.OSToken, mappedMessageType, 5303 messageSubject, messageBody, personId, personImage, 5304 personName, personProfile], 5305 this.params_.remoteRelay, 5306 messageSend_sync, 5307 this.params_.localRelay, 5308 null); 5309 5310 5311 }; 5312 5313 MyOpenSpace.MySpaceContainer.container_ = new MyOpenSpace.MySpaceContainer(); 5314 /** 5315 * A helper class used to coordinate the app's body onload 5316 * @constructor 5317 * @private 5318 * @private 5319 */ 5320 MyOpenSpace.OnLoad = function() { }; 5321 5322 5323 /** 5324 * Run on body onload, this executes all the registered onload handlers and calls 5325 * gadgets.util.runOnLoadHandlers (the public facing onload handler) when complete. 5326 * @static 5327 * @private 5328 * @memberOf MyOpenSpace.OnLoad 5329 */ 5330 MyOpenSpace.OnLoad.runOnLoadHandlers = function() { 5331 MyOpenSpace.OnLoad.raiseLoadedEvent(); 5332 gadgets.util.runOnLoadHandlers(); 5333 }; 5334 5335 /** 5336 * Function to alert the parent page that the app has finished loaded 5337 * @static 5338 * @private 5339 * @memberOf MyOpenSpace.OnLoad 5340 */ 5341 MyOpenSpace.OnLoad.raiseLoadedEvent = function(){ 5342 if(gadgets.views.getCurrentView().getName() !== gadgets.views.ViewType.HOME) return; 5343 5344 var p = gadgets.views.getParams(); 5345 var surface = gadgets.views.getCurrentView().getName(); 5346 _IFPC.call( 5347 p.panelId, 5348 "requestShowApp", 5349 [p.appid, surface.toLowerCase()], 5350 p.remoteRelay, 5351 null, 5352 p.localRelay, 5353 null); 5354 };/** 5355 * An extension of opensocial.Permission 5356 * @constructor 5357 * @private 5358 */ 5359 MyOpenSpace.Permission = function() { }; 5360 5361 /** 5362 * The available permission types 5363 * @class 5364 * @name MyOpenSpace.Permission.Field 5365 * @static 5366 * @private 5367 */ 5368 MyOpenSpace.Permission.Field = { 5369 DISPLAY_ON_PROFILE: "DisplayOnProfile", 5370 DISPLAY_ON_HOME: "DisplayOnHome", 5371 SEND_UPDATES_TO_FRIENDS: "SendUpdatesToFriends", 5372 SHOW_UPDATES_FROM_FRIENDS: "ShowUpdatesFromFriends", 5373 //ALLOW_SENDING_EMAILS: "AllowSendingEmails", 5374 ACCESS_TO_PRIVATE_VIDEOS_PHOTOS: "AccessToPrivateVideosPhotos", 5375 ACCESS_TO_PUBLIC_VIDEOS_PHOTOS: "AccessToPublicVideosPhotos" 5376 }; 5377 5378 5379 /** 5380 * The available permission settings that can be checked 5381 * @class 5382 * @name MyOpenSpace.Permission 5383 * @static 5384 */ 5385 MyOpenSpace.Permission = { 5386 /** 5387 * An object representing the permission to allow the app to appear on the viewer's profile. 5388 * @memberOf MyOpenSpace.Permission 5389 */ 5390 VIEWER_DISPLAY_ON_PROFILE: { 5391 user: opensocial.IdSpec.PersonId.VIEWER, 5392 permission: MyOpenSpace.Permission.Field.DISPLAY_ON_PROFILE, 5393 permissionIndicator : "DP" 5394 }, 5395 /** 5396 * An object representing the permission to allow the app to appear on the viewer's home page. 5397 * @memberOf MyOpenSpace.Permission 5398 */ 5399 VIEWER_DISPLAY_ON_HOME: { 5400 user: opensocial.IdSpec.PersonId.VIEWER, 5401 permission: MyOpenSpace.Permission.Field.DISPLAY_ON_HOME, 5402 permissionIndicator : "DH" 5403 }, 5404 /** 5405 * An object representing the permission to allow the app to send updates/notifications to the viewer's friends. 5406 * @memberOf MyOpenSpace.Permission 5407 */ 5408 VIEWER_SEND_UPDATES_TO_FRIENDS: { 5409 user: opensocial.IdSpec.PersonId.VIEWER, 5410 permission: MyOpenSpace.Permission.Field.SEND_UPDATES_TO_FRIENDS, 5411 permissionIndicator : "UT" 5412 }, 5413 /** 5414 * An object representing the permission to allow the app to show updates/notifications from the viewer's friends. 5415 * @memberOf MyOpenSpace.Permission 5416 */ 5417 VIEWER_SHOW_UPDATES_FROM_FRIENDS: { 5418 user: opensocial.IdSpec.PersonId.VIEWER, 5419 permission: MyOpenSpace.Permission.Field.SHOW_UPDATES_FROM_FRIENDS, 5420 permissionIndicator : "UF" 5421 }, 5422 /** 5423 * An object representing the permission to allow the app access to the viewer's private videos and photos. 5424 * @memberOf MyOpenSpace.Permission 5425 */ 5426 VIEWER_ACCESS_TO_PRIVATE_VIDEOS_PHOTOS: { 5427 user: opensocial.IdSpec.PersonId.VIEWER, 5428 permission: MyOpenSpace.Permission.Field.ACCESS_TO_PRIVATE_VIDEOS_PHOTOS, 5429 permissionIndicator : "PR" 5430 }, 5431 /** 5432 * An object representing the permission to allow the app access to the viewer's public videos and photos. 5433 * @memberOf MyOpenSpace.Permission 5434 */ 5435 VIEWER_ACCESS_TO_PUBLIC_VIDEOS_PHOTOS: { 5436 user: opensocial.IdSpec.PersonId.VIEWER, 5437 permission: MyOpenSpace.Permission.Field.ACCESS_TO_PUBLIC_VIDEOS_PHOTOS, 5438 permissionIndicator : "PB" 5439 }//, 5440 // /** 5441 // * An object representing the permission to allow the app to appear on the owner's profile. 5442 // * @memberOf MyOpenSpace.Permission 5443 // * @ignore 5444 // */ 5445 // OWNER_DISPLAY_ON_PROFILE: { 5446 // user: opensocial.IdSpec.PersonId.OWNER, 5447 // permission: MyOpenSpace.Permission.Field.DISPLAY_ON_PROFILE, 5448 // permissionIndicator : "DP" 5449 // }, 5450 // /** 5451 // * An object representing the permission to allow the app to appear on the owner's home page. 5452 // * @memberOf MyOpenSpace.Permission 5453 // * @ignore 5454 // */ 5455 // OWNER_DISPLAY_ON_HOME: { 5456 // user: opensocial.IdSpec.PersonId.OWNER, 5457 // permission: MyOpenSpace.Permission.Field.DISPLAY_ON_HOME, 5458 // permissionIndicator : "DH" 5459 // }, 5460 // /** 5461 // * An object representing the permission to allow the app to send updates/notifications to the owner's friends. 5462 // * @memberOf MyOpenSpace.Permission 5463 // * @ignore 5464 // */ 5465 // OWNER_SEND_UPDATES_TO_FRIENDS: { 5466 // user: opensocial.IdSpec.PersonId.OWNER, 5467 // permission: MyOpenSpace.Permission.Field.SEND_UPDATES_TO_FRIENDS, 5468 // permissionIndicator : "UT" 5469 // }, 5470 // /** 5471 // * An object representing the permission to allow the app to show updates/notifications from the owner's friends. 5472 // * @memberOf MyOpenSpace.Permission 5473 // * @ignore 5474 // */ 5475 // OWNER_SHOW_UPDATES_FROM_FRIENDS: { 5476 // user: opensocial.IdSpec.PersonId.OWNER, 5477 // permission: MyOpenSpace.Permission.Field.SHOW_UPDATES_FROM_FRIENDS, 5478 // permissionIndicator : "UF" 5479 // }, 5480 // /** 5481 // * An object representing the permission to allow the app access to the owner's private videos and photos. 5482 // * @memberOf MyOpenSpace.Permission 5483 // * @ignore 5484 // */ 5485 // OWNER_ACCESS_TO_PRIVATE_VIDEOS_PHOTOS: { 5486 // user: opensocial.IdSpec.PersonId.OWNER, 5487 // permission: MyOpenSpace.Permission.Field.ACCESS_TO_PRIVATE_VIDEOS_PHOTOS, 5488 // permissionIndicator : "PR" 5489 // }, 5490 // /** 5491 // * An object representing the permission to allow the app access to the owner's public videos and photos. 5492 // * @memberOf MyOpenSpace.Permission 5493 // * @ignore 5494 // */ 5495 // OWNER_ACCESS_TO_PUBLIC_VIDEOS_PHOTOS: { 5496 // user: opensocial.IdSpec.PersonId.OWNER, 5497 // permission: MyOpenSpace.Permission.Field.ACCESS_TO_PUBLIC_VIDEOS_PHOTOS, 5498 // permissionIndicator : "PB" 5499 // } 5500 }; 5501 5502 /** 5503 * Returns true if the current gadget has access to the specified 5504 * permission. If the gadget calls opensocial.requestPermission and permissions 5505 * are granted then this function must return true on all subsequent calls. 5506 * 5507 * @param {opensocial.Permission} permission 5508 * The <a href="opensocial.Permission.html">permission</a> 5509 * @return {Boolean} 5510 * True if the gadget has access for the permission; false if it doesn't 5511 * 5512 * @member opensocial 5513 * @private 5514 * @private 5515 */ 5516 MyOpenSpace.MySpaceContainer.prototype.hasPermission = function(permission) { 5517 var viewerDeny = gadgets.views.getParams().denyViewer; 5518 5519 //TODO this may not be true any more we need to checkt for BasicInformation. 5520 if (viewerDeny){ 5521 return false; 5522 } 5523 5524 if (permission === opensocial.Permission.VIEWER) { 5525 return true; 5526 } 5527 5528 var userPermissions; 5529 5530 if (permission && permission.user === opensocial.IdSpec.PersonId.VIEWER) { 5531 userPermissions = gadgets.views.getParams().viewerPerm; 5532 } 5533 else if (permission && permission.user === opensocial.IdSpec.PersonId.OWNER) { 5534 userPermissions = gadgets.views.getParams().ownerPerm; 5535 } 5536 else { 5537 throw "Invalid permission object." 5538 return; 5539 } 5540 5541 for (var i in userPermissions) { 5542 if (userPermissions[i] === permission.permissionIndicator) { 5543 return true; 5544 } 5545 } 5546 5547 return false; 5548 } 5549 5550 /** 5551 * An extension of opensocial.Person 5552 * @constructor 5553 * @private 5554 * @param {Array<opensocial.Person.Field || MyOpenSpace.Person.Field>} opt_params Contains an Array with opensocial.Person.Field or MyOpenSpace.Person.Field values with which to populate the object 5555 * @param {Boolean} opt_isOwner Sets the person as the owner 5556 * @param {Boolean} opt_isOwner Sets the person as the viewer 5557 */ 5558 MyOpenSpace.Person = function(opt_params, opt_isOwner, opt_isViewer) { 5559 opensocial.Person.call(this, opt_params, opt_isOwner, opt_isViewer); 5560 this["setField_"] = function(key,val) { this.fields_[key] = val; }; //TODO: find a better way to extend 5561 this._type = 0; 5562 }; 5563 5564 /** 5565 * The fields for the extended MyOpenSpace.Person 5566 * @class 5567 * @name MyOpenSpace.Person.Field 5568 * @static 5569 */ 5570 MyOpenSpace.Person.Field = opensocial.Person.Field; 5571 5572 /** 5573 * The URL of the medium version of the user's thumbnail 5574 * @memberOf MyOpenSpace.Person.Field 5575 */ 5576 MyOpenSpace.Person.Field.MEDIUM_IMAGE = "medimImage"; 5577 /** 5578 * The URL of the large version of the user's thumbnail 5579 * @memberOf MyOpenSpace.Person.Field 5580 */ 5581 MyOpenSpace.Person.Field.LARGE_IMAGE ="largeImage"; 5582 5583 5584 MyOpenSpace.Person.inherits(opensocial.Person); 5585 5586 /** 5587 * A class representing an PersonMood. 5588 * @constructor 5589 * @private 5590 */ 5591 MyOpenSpace.PersonMood = function() {}; 5592 /** 5593 * The fields for MyOpenSpace.PersonMood 5594 * @class 5595 * @name MyOpenSpace.PersonMood.Field 5596 * @static 5597 */ 5598 MyOpenSpace.PersonMood.Field = { 5599 /** 5600 * A string indicating the person mood. 5601 * @memberOf MyOpenSpace.PersonMood.Field 5602 */ 5603 MOOD:"MOOD", 5604 /** 5605 * A string indicating the person mood image url. 5606 * @memberOf MyOpenSpace.PersonMood.Field 5607 */ 5608 MOOD_IMAGE_URL:"MOOD_IMAGE_URL", 5609 /** 5610 * A string indicating the last date time the mood was modified. 5611 * @memberOf MyOpenSpace.PersonMood.Field 5612 */ 5613 MOOD_LAST_UPDATED:"MOOD_LAST_UPDATED" 5614 }; 5615 5616 /** 5617 * Returns the field specified by key 5618 * @param {String} key The key to search by 5619 * @return {MyOpenSpace.PersonMood || undefined} The PersonMood if found, nothing otherwise. 5620 */ 5621 MyOpenSpace.PersonMood.prototype.getField = function(key) { return this[key]; }; 5622 5623 /** 5624 * Writes a value to the field specified by the key 5625 * @param {String} key The key to search by. 5626 * @param {String} val The value to set. 5627 * @private 5628 * @private 5629 */ 5630 MyOpenSpace.PersonMood.prototype.setField_ = function(key,val) { this[key] = val; };/** 5631 * A class representing an PersonStatus. 5632 * @constructor 5633 * @private 5634 */ 5635 MyOpenSpace.PersonStatus = function() {}; 5636 /** 5637 * The fields for MyOpenSpace.PersonStatus 5638 * @class 5639 * @name MyOpenSpace.PersonStatus.Field 5640 * @static 5641 */ 5642 MyOpenSpace.PersonStatus.Field = { 5643 /** 5644 * A string indicating the person status. 5645 * @memberOf MyOpenSpace.PersonStatus.Field 5646 */ 5647 STATUS:"STATUS" 5648 }; 5649 /** 5650 * Returns the field specified by key 5651 * @param {String} key The key to search by 5652 * @return {MyOpenSpace.PersonStatus || undefined} The PersonStatus if found, nothing otherwise. 5653 */ 5654 MyOpenSpace.PersonStatus.prototype.getField = function(key) { return this[key]; }; 5655 /** 5656 * Writes a value to the field specified by the key 5657 * @param {String} key The key to search by. 5658 * @param {String} val The value to set. 5659 * @private 5660 * @private 5661 */ 5662 MyOpenSpace.PersonStatus.prototype.setField_ = function(key,val) { this[key] = val; };/** 5663 * A class representing a photo. 5664 * @constructor 5665 * @private 5666 */ 5667 MyOpenSpace.Photo = function() {}; 5668 5669 /** 5670 * The fields for MyOpenSpace.Photo 5671 * @class 5672 * @name MyOpenSpace.Photo.Field 5673 * @static 5674 */ 5675 MyOpenSpace.Photo.Field = { 5676 /** 5677 * A number representing a Photo's unique identifier. 5678 * @memberOf MyOpenSpace.Photo.Field 5679 */ 5680 PHOTO_ID:"PHOTO_ID", 5681 5682 /** 5683 * The RESTFUL URI with which to access the photo on the API. 5684 * @memberOf MyOpenSpace.Photo.Field 5685 */ 5686 PHOTO_URI:"PHOTO_URI", 5687 5688 /** 5689 * The URL of the photo. 5690 * @memberOf MyOpenSpace.Photo.Field 5691 */ 5692 IMAGE_URI:"IMAGE_URI", 5693 5694 /** 5695 * The photo's caption. 5696 * @memberOf MyOpenSpace.Photo.Field 5697 */ 5698 CAPTION:"CAPTION" 5699 }; 5700 5701 /** 5702 * Returns the field specified by key 5703 * @param {String} key The key to search by 5704 * @return {MyOpenSpace.Photo || undefined} The photo if found, nothing otherwise. 5705 */ 5706 MyOpenSpace.Photo.prototype.getField = function(key) { return this[key]; }; 5707 5708 /** 5709 * Writes a value to the field specified by the key 5710 * @param {String} key The key to search by. 5711 * @param {String} val The value to set. 5712 * @private 5713 * @private 5714 */ 5715 MyOpenSpace.Photo.prototype.setField_ = function(key,val) { this[key] = val; };/** 5716 * Just a place-holder in order to extend MyOpenSpace.PostTo 5717 * @ignore 5718 */ 5719 MyOpenSpace.PostTo = {}; 5720 5721 /** 5722 * Enumerates the targets for PostTo 5723 * @static 5724 * @class 5725 * @private 5726 * @name MyOpenSpace.PostTo.Targets 5727 */ 5728 MyOpenSpace.PostTo.Targets = { 5729 /** 5730 * A user's profile, the specific section is specified on the Post To UI 5731 * @memberOf MyOpenSpace.PostTo.Targets 5732 */ 5733 PROFILE:"PROFILE", 5734 5735 /** 5736 * A message to another user's inbox 5737 * @memberOf MyOpenSpace.PostTo.Targets 5738 */ 5739 SEND_MESSAGE:"SEND_MESSAGE", 5740 5741 /** 5742 * A user's comments 5743 * @memberOf MyOpenSpace.PostTo.Targets 5744 */ 5745 COMMENTS:"COMMENTS", 5746 5747 /** 5748 * A user's bulletins 5749 * @memberOf MyOpenSpace.PostTo.Targets 5750 */ 5751 BULLETINS:"BULLETINS", 5752 5753 /** 5754 * A user's blog 5755 * @memberOf MyOpenSpace.PostTo.Targets 5756 */ 5757 BLOG:"BLOG", 5758 5759 /** 5760 * Request to share an app with another user 5761 * @memberOf MyOpenSpace.PostTo.Targets 5762 */ 5763 SHARE_APP:"SHARE_APP" 5764 }; 5765 5766 5767 /** 5768 * Enumerates the PostTo result 5769 * @static 5770 * @class 5771 * @name MyOpenSpace.PostTo.Result 5772 */ 5773 MyOpenSpace.PostTo.Result = { 5774 /** 5775 * An error occurred in postTo request 5776 * @memberOf MyOpenSpace.PostTo.Result 5777 */ 5778 ERROR: -1, 5779 5780 /** 5781 * User pressed cancel before completion 5782 * @memberOf MyOpenSpace.PostTo.Result 5783 */ 5784 CANCELLED: 0, 5785 5786 /** 5787 * Successful postTo request completed 5788 * @memberOf MyOpenSpace.PostTo.Result 5789 */ 5790 SUCCESS: 1 5791 };/** 5792 * @class 5793 * @name MyOpenSpace.RequestProcessor_ 5794 * @private 5795 * @private 5796 * MySpace's implementation of a data request manager; linking security, queueing, callbacks, responses, and request actions all together. 5797 * Created to abstract away from OpenSocial's base objects so MySpace can link in EXTENDED entities/methods more easily. 5798 * 5799 */ 5800 if (typeof(MyOpenSpace.RequestProcessor_) == "undefined") MyOpenSpace.RequestProcessor_ = {}; 5801 5802 /** 5803 * Do not instantiate. Each DataRequest will create its' own RequestProcessor_ and direct work items through it automatically. 5804 * @private 5805 * @private 5806 * @constructor MyOpenSpace.RequestProcessor_ 5807 */ 5808 MyOpenSpace.RequestProcessor_ = function(){ 5809 //this._resultCache = new QuickHash(); 5810 this.executionInterval_ = 200; 5811 //this.executionModel_ = MyOpenSpace.RequestProcessor_.ExecutionModel_.ASYNC; 5812 this.executionModel_ = MyOpenSpace.RequestProcessor_.ExecutionModel_.SERIAL; 5813 //this.executionModel_ = MyOpenSpace.RequestProcessor_.ExecutionModel_.THROTTLED 5814 this.requestActions_ = null; 5815 this.TotalWorkItems; 5816 this.WorkItemsToProcess; 5817 this.WorkItemsProcessed; 5818 //this._readyToSend = false; 5819 this.paused_ = false; 5820 this.aborted_ = false; 5821 this.authorizationSchemaSet_ = false; 5822 5823 this.init(); 5824 }; 5825 5826 /** 5827 * Specifies how the RequestProcessor will process the queue of work items. 5828 * @static 5829 * @class 5830 * @name MyOpenSpace.RequestProcessor_.ExecutionModel_. 5831 * @private 5832 * @private 5833 */ 5834 MyOpenSpace.RequestProcessor_.ExecutionModel_ = { 5835 /** 5836 * @property {int} SERIAL Executes the queue async one after each other. Essentially a blocking async. 5837 * @private 5838 */ 5839 SERIAL: "SERIAL", 5840 5841 /** 5842 * Not currently supported. 5843 * @property {int} ASYNC Executes the queue async one after each other, without blocking. 5844 * @private 5845 */ 5846 ASYNC: "ASYNC", 5847 5848 /** 5849 * Not currently supported. 5850 * @property {int} THROTTLED Same as SERIAL, but with a delay between each work item processed. Use throttleProcessingSpeed(msDelay) to set delay time. 5851 * @private 5852 */ 5853 THROTTLED: "THROTTLED" 5854 }; 5855 5856 /** 5857 * @class 5858 * @name MyOpenSpace.RequestProcessor_ 5859 * @private 5860 * @private 5861 */ 5862 MyOpenSpace.RequestProcessor_.prototype = { 5863 /** 5864 * Init handles all initialization for the RequestProcessor_. 5865 * @memberOf MyOpenSpace.RequestProcessor_ 5866 * @private 5867 */ 5868 init: function() { 5869 this.workItemPool_ = new this.delayShiftQueue(); 5870 }, 5871 5872 /** 5873 * prepareForSend will setup the queue in preparation for processing the work items. 5874 * @param {opensocial.DataRequest} ptr Pointer to DataRequest 5875 * @memberOf MyOpenSpace.RequestProcessor_ 5876 * @private 5877 */ 5878 prepareForSend : function(ptr) { 5879 //this._readyToSend = true; 5880 this.requestActions_ = new MyOpenSpace.DataRequest.RequestActions_(ptr); 5881 //startProcessing(); 5882 //this.workItemPool_.prioritize(); 5883 }, 5884 5885 /** 5886 * setAuthorization sets the authorization template used to verify/set authorizations on each DataRequest's request. 5887 * @memberOf MyOpenSpace.RequestProcessor_ 5888 * @param {Object} template The authorization template to apply to this DataRequest. 5889 * @private 5890 */ 5891 setAuthorization: function(template) { 5892 this.authTemplate_ = template; 5893 this.authorizationSchemaSet_ = true; 5894 }, 5895 5896 /** 5897 * addWorkItem will add a work item to the RequestProcessor's queue. 5898 * @memberOf MyOpenSpace.RequestProcessor_ 5899 * @param {MyOpenSpace.RequestProcessor_.WorkItem} workItem The work item to add to the queue. 5900 * @private 5901 */ 5902 addWorkItem: function(workItem) { // was:addWorkItem: function(workItem, priority) { 5903 //if (!this._readyToSend){ 5904 //TODO: put hasPermission/requestPermission here 5905 //workItem.priority = priority; 5906 this.workItemPool_.push(workItem); 5907 5908 //} 5909 }, 5910 5911 /** 5912 * startProcessing will being executing work items from the queue, as defined by the ExecutionModel_. 5913 * @memberOf MyOpenSpace.RequestProcessor_ 5914 * @private 5915 */ 5916 startProcessing: function() { 5917 switch (this.executionModel_) { 5918 case MyOpenSpace.RequestProcessor_.ExecutionModel_.SERIAL: //one after the other 5919 this.process(); 5920 break; 5921 case MyOpenSpace.RequestProcessor_.ExecutionModel_.ASYNC: // all async at once 5922 for (var i=0;i<=this.workItemPool_.size();i++) 5923 { 5924 var workItem = this.workItemPool_.pop(); 5925 this.process(workItem); 5926 } 5927 break; 5928 case MyOpenSpace.RequestProcessor_.ExecutionModel_.THROTTLED: // one after the other + delay 5929 this.processWithDelay(); 5930 break; 5931 } 5932 }, 5933 5934 /** 5935 * process will execute a workItem 5936 * @param {MyOpenSpace.RequestProcessor_.WorkItem} workItem to process; if omitted - pop the next work item from queue. 5937 * @memberOf MyOpenSpace.RequestProcessor_ 5938 * @private 5939 */ 5940 process: function(workItem) { 5941 if (workItem) { 5942 this.requestActions_[workItem.type](workItem); 5943 return; 5944 } 5945 5946 workItem = this.workItemPool_.pop(); 5947 if(workItem) 5948 this.requestActions_[workItem.type](workItem); 5949 5950 if(this.executionModel_ === MyOpenSpace.RequestProcessor_.ExecutionModel_.THROTTLED) 5951 this.processWithDelay(); 5952 //else if (this.workItemPool_.size() > 0 && !this.paused_ && !this.aborted_) 5953 //this.process(); // queue up next work item immediately 5954 }, 5955 5956 /** 5957 * processWithDelay will execute a workItem, then set an interval of executionInterval before executing the next work item; so long as pauseProcessing() or abortProcessing() has not be invoked. 5958 * @param {MyOpenSpace.RequestProcessor_.WorkItem} workItem to process; if omitted - pop the next work item from queue. 5959 * @memberOf MyOpenSpace.RequestProcessor_ 5960 * @private 5961 */ 5962 processWithDelay: function() { 5963 //var workItem = this.workItemPool_.pop(); 5964 var pointer = this; 5965 if (pointer.workItemPool_.size() > 0 && !pointer.paused_ && !pointer.aborted_) 5966 setTimeout(function () { pointer.process(); }, pointer.executionInterval_); // queue up next work item after executionInterval ms 5967 //this.requestActions_[workItem.type](workItem); 5968 }, 5969 5970 /** 5971 * pauseProcessing will pause the execution of SERIAL and THROTTLED execution models, resumeProcessing() will continue execution. 5972 * @memberOf MyOpenSpace.RequestProcessor_ 5973 * @private 5974 */ 5975 pauseProcessing: function() { 5976 this.paused_ = true; 5977 }, 5978 5979 /** 5980 * abortProcessing will stop the execution of SERIAL and THROTTLED execution models, with no option to recover. 5981 * @memberOf MyOpenSpace.RequestProcessor_ 5982 * @private 5983 */ 5984 abortProcessing: function() { 5985 this.aborted_ = true; 5986 }, 5987 5988 /** 5989 * resumeProcessing will unpause the execution of SERIAL and THROTTLED execution models. 5990 * @memberOf MyOpenSpace.RequestProcessor_ 5991 * @private 5992 */ 5993 resumeProcessing: function() { 5994 this.paused_ = false; 5995 }, 5996 5997 /** 5998 * throttleProcessingSpeed sets the delay between work item processing in THROTTLED execution model. 5999 * @memberOf MyOpenSpace.RequestProcessor_ 6000 * @private 6001 */ 6002 throttleProcessingSpeed: function(msDelay) { 6003 this.executionInterval_ = msDelay; 6004 }, 6005 6006 /** 6007 * delayShiftQueue is a delay shift queue implementation. Only shifts queue after (len/2) pops to save cycles. 6008 * @memberOf MyOpenSpace.RequestProcessor_ 6009 * @private 6010 */ 6011 delayShiftQueue: function(){ 6012 var q=new Array(); 6013 var qSpace=0; 6014 6015 /** 6016 * push will add a work item to the queue 6017 * @param {MyOpenSpace.RequestProcessor_.WorkItem} element Work item to add to the queue. 6018 * @private 6019 */ 6020 this.push=function(element){ 6021 q.push(element); 6022 }; 6023 6024 /** 6025 * pop will return the next work item in the queue. Queue will be shifted once length/2 calls have been made to this function. 6026 * @private 6027 */ 6028 this.pop=function(){ 6029 if (q.length){ 6030 var element=q[qSpace]; 6031 if (++qSpace*2 >= q.length){ 6032 for (var i=qSpace;i<q.length;i++) q[i-qSpace]=q[i]; 6033 q.length-=qSpace; 6034 qSpace=0; 6035 } 6036 return element; 6037 } else { 6038 return undefined; 6039 } 6040 }; 6041 6042 /** 6043 * size will return the number of work items in the queue. 6044 * @private 6045 */ 6046 this.size=function(){ 6047 return q.length; 6048 }; 6049 6050 /** 6051 * prioritize will sort the queue based on priority (critical, high, normal, low) 6052 * @private 6053 */ 6054 this.prioritize=function(){ 6055 q.sort(this.prioritySort_); 6056 }; 6057 6058 /** 6059 * prioritySort_ is an internal comparer for ordering work items based on priority. 6060 * @private 6061 */ 6062 this.prioritySort_=function(a,b){ 6063 if (a.priority > b.priority) return -1; 6064 if (a.priority == b.priority) return 0; 6065 if (a.priority < b.priority) return 1; 6066 }; 6067 } 6068 }; 6069 6070 /** 6071 * Adds work item properties to a DataRequest for processing within the queue. 6072 * @class 6073 * @name MyOpenSpace.RequestProcessor_.WorkItem 6074 * @private 6075 */ 6076 if (typeof(MyOpenSpace.RequestProcessor_.WorkItem) == "undefined") MyOpenSpace.RequestProcessor_.WorkItem = {}; 6077 6078 /** 6079 * @constructor MyOpenSpace.RequestProcessor_.WorkItem 6080 * @param {MyOpenSpace._DataRequest} request The datarequest associated with the work item. 6081 * @private 6082 */ 6083 MyOpenSpace.RequestProcessor_.WorkItem = new function(request){ 6084 this.Request = request; 6085 this.CreationTime = new Date().getTime(); //ms in epoch time 6086 this.QueueTime = null; 6087 this.WorkItemType = null; 6088 this.ProcessStartTime = null; 6089 this.ProcessEndTime = null; 6090 this.Priority = MyOpenSpace.RequestProcessor_.WorkItem.NORMAL; 6091 }; 6092 6093 /** 6094 * Defines level of priority for work items. Processed in this order: CRITICAL -> HIGH -> NORMAL -> LOW 6095 * Allows for a queue's priority to be calculated as a sum of all work item's priorities. 6096 * We may want to add in a dependency object for work items, so one may process first if another depends on it 6097 * Note: Currently we don't use priorities for anything. 6098 * @static 6099 * @class 6100 * @name Priority 6101 * @private 6102 */ 6103 MyOpenSpace.RequestProcessor_.WorkItem.Priority = { 6104 /** 6105 * The integer weight for a low priority item. Decreases queue priority. 6106 * @memberOf MyOpenSpace.RequestProcessor_.WorkItem.Priority 6107 * @private 6108 */ 6109 "LOW": -1, 6110 6111 /** 6112 * The integer weight for a normal priority item. Does not affect queue priority. 6113 * @memberOf MyOpenSpace.RequestProcessor_.WorkItem.Priority 6114 * @private 6115 */ 6116 "NORMAL": 0, 6117 6118 /** 6119 * The integer weight for a high priority item. Increases queue's priority. 6120 * @memberOf MyOpenSpace.RequestProcessor_.WorkItem.Priority 6121 * @private 6122 */ 6123 "HIGH": 1, 6124 6125 /** 6126 * The integer weight for a critical priority item. Increases queue's priority by twice magnitude of high. 6127 * @memberOf MyOpenSpace.RequestProcessor_.WorkItem.Priority 6128 * @private 6129 */ 6130 "CRITICAL": 2 6131 };/** 6132 * A stringbuilder implementation similar to .net - use in place of += for any strcat operations 6133 * @constructor 6134 * @name MyOpenSpace.StringBuilder 6135 */ 6136 MyOpenSpace.StringBuilder = function(value) { 6137 this.strings_ = []; 6138 this.append(value); 6139 }; 6140 /** 6141 * Appends a string 6142 * @member MyOpenSpace.StringBuilder 6143 */ 6144 MyOpenSpace.StringBuilder.prototype.append = function (value) { 6145 if (value) this.strings_.push(value); 6146 }; 6147 6148 /** 6149 * Clears the stringbuilder 6150 * @member MyOpenSpace.StringBuilder 6151 */ 6152 MyOpenSpace.StringBuilder.prototype.clear = function () { 6153 this.strings_.length = 0; 6154 }; 6155 6156 /** 6157 * Returns the string built 6158 * @member MyOpenSpace.StringBuilder 6159 */ 6160 MyOpenSpace.StringBuilder.prototype.toString = function () { 6161 return this.strings_.join(""); 6162 };/** 6163 * A class representing a video. 6164 * @constructor 6165 * @private 6166 */ 6167 MyOpenSpace.Video = function() {}; 6168 6169 /** 6170 * The fields for MyOpenSpace.Video 6171 * @class 6172 * @name MyOpenSpace.Video.Field 6173 * @static 6174 */ 6175 MyOpenSpace.Video.Field = { 6176 /** 6177 * A number representing a Video's unique identifier. 6178 * @memberOf MyOpenSpace.Video.Field 6179 */ 6180 VIDEO_ID:"VIDEO_ID", 6181 6182 /** 6183 * The RESTFUL URI with which to access the video on the API. 6184 * @memberOf MyOpenSpace.Video.Field 6185 */ 6186 VIDEO_URI:"VIDEO_URI", 6187 6188 /** 6189 * The video's title. 6190 * @memberOf MyOpenSpace.Video.Field 6191 */ 6192 TITLE:"TITLE", 6193 6194 /** 6195 * The date the video was created. 6196 * @memberOf MyOpenSpace.Video.Field 6197 */ 6198 DATE_CREATED:"DATE_CREATED", 6199 6200 /** 6201 * The date the video was last updated. 6202 * @memberOf MyOpenSpace.Video.Field 6203 */ 6204 LAST_UPDATE:"LAST_UPDATE", 6205 6206 /** 6207 * An integer representing the media type for this video. 6208 * @memberOf MyOpenSpace.Video.Field 6209 */ 6210 MEDIA_TYPE:"MEDIA_TYPE", 6211 6212 /** 6213 * A URL for the thumbnail image associated with this video. 6214 * @memberOf MyOpenSpace.Video.Field 6215 */ 6216 THUMB_URI:"THUMB_URI", 6217 6218 /** 6219 * A description of the video. 6220 * @memberOf MyOpenSpace.Video.Field 6221 */ 6222 DESCRIPTION:"DESCRIPTION", 6223 6224 /** 6225 * The current status of the video, such as "ProcessingFailed" 6226 * @memberOf MyOpenSpace.Video.Field 6227 */ 6228 MEDIA_STATUS:"MEDIA_STATUS", 6229 6230 /** 6231 * The length of the video. 6232 * @memberOf MyOpenSpace.Video.Field 6233 */ 6234 RUN_TIME:"RUN_TIME", 6235 6236 /** 6237 * An integer representing the number of views the video has currently received. 6238 * @memberOf MyOpenSpace.Video.Field 6239 */ 6240 TOTAL_VIEWS:"TOTAL_VIEWS", 6241 6242 /** 6243 * An integer representing the number of comments the video has currently received. 6244 * @memberOf MyOpenSpace.Video.Field 6245 */ 6246 TOTAL_COMMENTS:"TOTAL_COMMENTS", 6247 6248 /** 6249 * An integer representing the rating the video has currently received. 6250 * @memberOf MyOpenSpace.Video.Field 6251 */ 6252 TOTAL_RATING:"TOTAL_RATING", 6253 6254 /** 6255 * An integer representing the number of votes the video has currently received. 6256 * @memberOf MyOpenSpace.Video.Field 6257 */ 6258 TOTAL_VOTES:"TOTAL_VOTES", 6259 6260 /** 6261 * A string representing the video's country, in terms of identifying culture, not necessarily geographic location. 6262 * @memberOf MyOpenSpace.Video.Field 6263 */ 6264 COUNTRY:"COUNTRY", 6265 6266 /** 6267 * A string representing the video's language. 6268 * @memberOf MyOpenSpace.Video.Field 6269 */ 6270 LANGUAGE:"LANGUAGE" 6271 }; 6272 6273 /** 6274 * Returns the field specified by key 6275 * @param {String} key The key to search by 6276 * @return {MyOpenSpace.Video || undefined} The video if found, nothing otherwise. 6277 */ 6278 MyOpenSpace.Video.prototype.getField = function(key) { return this[key]; }; 6279 6280 /** 6281 * Writes a value to the field specified by the key 6282 * @param {String} key The key to search by. 6283 * @param {String} val The value to set. 6284 * @private 6285 * @private 6286 */ 6287 MyOpenSpace.Video.prototype.setField_ = function(key,val) { this[key] = val; };