1 var REST = function() 2 { 3 var REST = {}; 4 var myResult = []; 5 var myHasErrors = false; 6 logRequest(); 7 8 //Field PropertyWrappers to collect the version number and the replaced date 9 var kReplaceDate = new Property("http://mediabeacon.com/ns/default/1.0/", "replaceDate"); 10 11 /** 12 * the callback for the REST call (savedSelections.js, directories.js, etc) 13 * @type {null} 14 */ 15 var myCallback = null; 16 17 /** 18 * All of the parameters given in the request 19 * @type {{}} 20 */ 21 var myRequestParameters = getParameters(); 22 23 /** 24 * Enable or disable adding data like name, path, height, etc... 25 * @type {boolean} 26 */ 27 var myVerbose = !!myRequestParameters.verbose ? myRequestParameters.verbose: false; 28 29 /** 30 * add the mtime to the response if the mtime parameter is set to true 31 * @type {boolean} 32 */ 33 var myMtime = !!myRequestParameters.mtime ? myRequestParameters.mtime: false; 34 35 /** 36 * Parameter to collect the document report. 37 * this is slow so we should exclude by default 38 * @type {boolean} 39 */ 40 var myCollectDocumentReport = !!myRequestParameters.documentLinks ? myRequestParameters.documentLinks: false; 41 42 /** 43 * Controls whether processing will stop on the first error. (Default: true.) 44 * @type {boolean} 45 */ 46 var myStopOnFirstError = true; 47 48 /** 49 * Adds an error object to the response 50 * 51 * @param theHttpCode 52 * @param theErrorMessage 53 * @param theException 54 */ 55 REST.pushError = function(theHttpCode, theErrorMessage, theException) 56 { 57 // If an error is not provided then we should just make it a 500 error. 58 if (!theHttpCode) 59 { 60 theHttpCode = REST.errors.e500; 61 } 62 63 if (!!theException) 64 { 65 logger.error(stack(theException)); 66 } 67 myHasErrors = true; 68 69 // Set the code in the header. 70 context.setResponseHeader('status', theHttpCode.code); 71 72 REST.push(null, { 73 error: { 74 message: theErrorMessage, 75 http: theHttpCode, 76 } 77 }); 78 }; 79 80 /** 81 * Returns true if we have encountered an error 82 */ 83 REST.hasErrors = function() 84 { 85 return myHasErrors; 86 }; 87 88 /** 89 * Push an object into the response 90 */ 91 REST.push = function(theFileOrFolder, theJSON, theDoFilter) 92 { 93 if (!!theFileOrFolder) 94 { 95 theJSON = REST.getInfo(theFileOrFolder, theJSON); 96 } 97 if (theDoFilter && !!theJSON && !REST.filterMatch(theJSON)) 98 { 99 return; 100 } 101 myResult[myResult.length] = theJSON; 102 }; 103 104 /** 105 * Remove the last added object to myResult. 106 * Not commonly used. 107 * 108 * Helpful for delete because we can add the file/folder to myResult with all of its asset info, then delete it. 109 * if we fail to delete the item, we still need to manually pop the object from myResult. 110 */ 111 REST.pop = function() 112 { 113 myResult.length --; 114 }; 115 116 /** 117 * Set the callback 118 * @param theCallback a function that takes in a managed file and pushes objects to the response object 119 */ 120 REST.setCallback = function(theCallback) 121 { 122 myCallback = theCallback; 123 }; 124 125 /** 126 * Sets whether to stop processing the REST call on the first error. (Default is true.) 127 * @param theStop true if so, false if no. 128 */ 129 REST.setStopOnFirstError = function (theStop) 130 { 131 myStopOnFirstError = theStop; 132 }; 133 134 /** 135 * Checks whether to stop processing the REST call on the first error. 136 * @return theStop true if so, false if no. 137 */ 138 REST.getStopOnFirstError = function () 139 { 140 return myStopOnFirstError; 141 }; 142 143 /** 144 * Executes the callback with the array of asset id's or the resolver url 145 */ 146 REST.execute = function(theExecuteOverParameter) 147 { 148 try 149 { 150 var aResolver = null; 151 152 if (!!myRequestParameters.resolver) 153 { 154 //Iterate over Resolver 155 aResolver = myRequestParameters.resolver; 156 searchManager.searchByResolverUrl(aResolver, context.getUser().userId, errorCheckingCallback); 157 } else if (!!theExecuteOverParameter) 158 { 159 //Iterate over the passed in parameter name 160 var aValues = myRequestParameters[theExecuteOverParameter]; 161 if (!!aValues) 162 { 163 if (!Array.isArray(aValues)) 164 { 165 aValues = [aValues]; 166 } 167 for (var i in aValues) 168 { 169 errorCheckingCallback(aValues[i]); 170 } 171 } 172 } else if (!!myRequestParameters.ids) 173 { 174 //Iterate over asset ids 175 if (!Array.isArray(myRequestParameters.ids)) 176 { 177 myRequestParameters.ids = [myRequestParameters.ids]; 178 } 179 myRequestParameters.ids = searchManager.filterByACL(myRequestParameters.ids); 180 for (var i in myRequestParameters.ids) 181 { 182 errorCheckingCallback(fileManager.getFileObjectById(myRequestParameters.ids[i])); 183 } 184 } else 185 { 186 //just execute the callback 187 errorCheckingCallback(); 188 } 189 } catch (anE) 190 { 191 REST.pushError(REST.errors.e500, "Failed to execute. Check the workflow logs for more information", anE); 192 } finally { 193 REST.setStopOnFirstError(true); 194 } 195 return REST.formatResponse(myResult); 196 }; 197 198 /** 199 * Returns a string to be returned from the workflow. 200 * Uses JSONP if the "callback" parameter is defined. 201 * if the "pretty" parameter is set to true we will format the response with newlines in the JSON 202 */ 203 REST.formatResponse = function(theResponseObject) 204 { 205 var aResponseString = ""; 206 if (!!myRequestParameters.pretty) 207 { 208 aResponseString = JSON.stringify(theResponseObject, null, 2); 209 } else 210 { 211 aResponseString = JSON.stringify(theResponseObject); 212 } 213 var aCallback = context.getParameter("callback"); 214 return !!aCallback ? aCallback + "(" + aResponseString + ");" : aResponseString; 215 }; 216 217 REST.filterMatch = function(theObject) 218 { 219 var anAllowForFilter = ["id", "name", "path", "height", "width", "bytes", "lastModified", "mimeType", "description", "type", "shared", "public", "count"]; 220 for (var aParameter in myRequestParameters) 221 { 222 if (anAllowForFilter.indexOf(aParameter) < 0) 223 { 224 continue; 225 } 226 var aFilterValue = myRequestParameters[aParameter]; 227 var anAssetValue = theObject[aParameter]; 228 if (anAssetValue === undefined) 229 { 230 //don't filter on undefined attributes 231 return false; 232 } 233 if (!isNaN(anAssetValue)) 234 { 235 //number values 236 if (isNaN(aFilterValue) && (aFilterValue.indexOf(">") == 0 || aFilterValue.indexOf("<") == 0)) 237 { 238 //Range filter 239 var aGtLt = aFilterValue.substring(0, 1); 240 var aNum = parseInt(aFilterValue.substring(1)); 241 if ((aGtLt == ">" && anAssetValue < aNum) || (aGtLt == "<" && anAssetValue > aNum)) 242 { 243 return false; 244 } 245 } else if (anAssetValue != aFilterValue) 246 { 247 return false; 248 } 249 } else 250 { 251 if (!!aFilterValue && !!anAssetValue) 252 { 253 if (aFilterValue.toString().indexOf("*") >= 0) 254 { 255 var aRegEx = new RegExp("^" + aFilterValue.split("*").join(".*")+ "$"); 256 if (!aRegEx.test(anAssetValue)) 257 { 258 return false; 259 } 260 } else if (anAssetValue != aFilterValue) 261 { 262 return false; 263 } 264 } 265 } 266 267 } 268 return true; 269 }; 270 271 /** 272 * Gets the standard asset info given an array of asset ids 273 * @param theAssetIds 274 */ 275 REST.getAssetInfo = function(theAssetIds) 276 { 277 var anAssetInfo = []; 278 for (var i in theAssetIds) 279 { 280 var anAsset = fileManager.getFileObjectById(theAssetIds[i]); 281 if (!!anAsset) 282 { 283 anAssetInfo.push(REST.getInfo(anAsset, {})); 284 } else { 285 logger.config("REST.getAssetInfo() asset doesn't exist by id: " + theAssetIds[i]); 286 } 287 } 288 return anAssetInfo; 289 }; 290 291 /** 292 * returns the acl relative path given the MB relative path 293 * @param theFullPath 294 * @returns {string|void|*|XML} 295 */ 296 REST.getACLRelativePath = function(theFullPath) 297 { 298 var aUsersRootPath = context.getACL().getRootPath(); 299 if (aUsersRootPath == null && aUsersRootPath == "") 300 { 301 var aUsersAcls = context.getUser().getPrimaryGroup().getACLs(); 302 if (aUsersAcls.length <= 0) 303 { 304 aUsersRootPath = null; 305 } else 306 { 307 aUsersRootPath = aUsersAcls[0].getRootPath(); 308 } 309 } 310 if (aUsersRootPath == null) 311 { 312 throw "Couldn't find ACL for current user"; 313 } 314 var aPath = theFullPath.replace(aUsersRootPath, ""); 315 return aPath == "" ? "/" : aPath; 316 }; 317 318 /** 319 * Adds the acl root path to thePath if the user is in a subroot acl 320 * @param thePath 321 * @returns {*} 322 */ 323 REST.getFullPath = function(thePath) 324 { 325 thePath = !thePath ? "" : thePath; 326 var aPath = context.getACL().getRootPath() + thePath; 327 //normalize any paths like Assets//test/ to Assets/test/ 328 aPath = aPath.split("//").join("/"); 329 return aPath; 330 }; 331 332 /** 333 * Is file? 334 * 335 * @param theFile the file to check 336 */ 337 REST.isFile = function (theFile) 338 { 339 return fileManager.isFile(theFile.path) || theFile instanceof UnmanagedFile; 340 }; 341 342 /** 343 * Returns the apikey request parameter and value in string form 344 * @returns {string} 345 */ 346 REST.getAuthParam = function() 347 { 348 return "apikey=" + apiKeyManager.getOrCreateApiKey("", context.getUser().username) + "&acl_id=" + context.getACL().id; 349 }; 350 351 /** 352 * Given a field id like "http://purl.org/dc/elements/1.1/ subject" or "database record_id" or "record_id" 353 * @param theFieldId 354 * @returns {Property} 355 */ 356 REST.getProperty = function(theFieldId) 357 { 358 try 359 { 360 if (theFieldId.indexOf(" ") < 0) 361 { 362 //assume its a DB field 363 return new Property("database", theFieldId); 364 } else 365 { 366 var aFieldSet = theFieldId.split(' '); 367 return new Property(aFieldSet[0], aFieldSet[1]); 368 } 369 } catch (anE) 370 { 371 REST.pushError(REST.errors.e404, "Failed to find the field for the field ID: " + theFieldId, anE); 372 return null; 373 } 374 }; 375 376 /** 377 * Call another REST workflow with the parameters 378 * @param theWorkflowName 379 * @param theParameters 380 */ 381 REST.callRESTWorkflow = function(theWorkflowName, theParameters) 382 { 383 var aParameters = new Parameters(); 384 if (!!myRequestParameters["verbose"]) 385 { 386 aParameters.put("verbose", myRequestParameters["verbose"]); 387 } 388 if (!!myRequestParameters["fields"]) 389 { 390 aParameters.put("fields", myRequestParameters["fields"]); 391 } 392 for (var aParam in theParameters) 393 { 394 aParameters.put(aParam, JSON.stringify(theParameters[aParam])); 395 } 396 var aWorkflow = new Workflow("Renditions/Workflows/_internal/restapi/v2/" + theWorkflowName + ".xmpwf"); 397 var aResponse = aWorkflow.trigger(aParameters); 398 try 399 { 400 return JSON.parse(aResponse); 401 } catch(anE) 402 { 403 return aResponse; 404 } 405 }; 406 407 REST.AssetTriggers = Object.freeze({ 408 Modified: "asset modified", 409 Added: "asset added", 410 Removed: "asset removed", 411 Downloaded: "asset downloaded" 412 }); 413 414 REST.triggerAssetBasedWorkflows = function(theType, theFile, theModificationsIfAny) 415 { 416 var aStub = {}; 417 if (!context.getParameter("triggerAssetBasedWorkflow", true)) 418 { 419 return false; 420 } 421 422 aStub.ok = false; 423 aStub.type = theType; 424 425 switch (theType) 426 { 427 case REST.AssetTriggers.Modified: 428 workflowManager.triggerAssetModified(theFile, theModificationsIfAny); 429 aStub.ok = true; 430 aStub.changes = theModificationsIfAny; 431 break; 432 case REST.AssetTriggers.Added: 433 workflowManager.triggerAssetAdded(theFile); 434 aStub.ok = true; 435 break; 436 case REST.AssetTriggers.Removed: 437 workflowManager.triggerAssetRemoved(theFile); 438 aStub.ok = true; 439 break; 440 case REST.AssetTriggers.Downloaded: 441 workflowManager.triggerAssetDownloaded(theFile); 442 aStub.ok = true; 443 break; 444 } 445 446 return aStub; 447 }; 448 449 REST.addToChangeList = function(theChangeList, theProperty, theOld, theNew) 450 { 451 theChangeList[theProperty.fieldId] = { 452 "old": typeof(theOld) === "object" ? theOld : theOld.toString(), 453 "new": typeof(theNew) === "object" ? theNew : theNew.toString(), 454 "type": theProperty.getFieldType() 455 }; 456 457 return theChangeList; 458 }; 459 460 REST.formatDiscussionList = function(theDiscussionSet, theLimit, theOrder) 461 { 462 var aFormattedList = []; 463 464 if (theDiscussionSet != null) 465 { 466 // Set the limit if it's too large. 467 if (theLimit && theLimit > theDiscussionSet.length) 468 { 469 theLimit = theDiscussionSet.length; 470 } 471 472 // Set the start: either 0 or the end of the array. 473 var aStartIndex = theOrder === 'desc' ? theDiscussionSet.length - 1 : 0; 474 475 // Pick where to stop: either the limit requested or the discussion set length or 0, depending on the order. 476 var aLimit = !isNaN(theLimit) ? theLimit : theDiscussionSet.length; 477 478 // Set the actual array index. 479 var aPlacementIndex = 0; 480 481 // Loop through them and add a useful item to the array. 482 while (true) 483 { 484 aFormattedList[aPlacementIndex] = {}; 485 486 // Get the sub entries in the discussion. 487 var aSubFields = theDiscussionSet.getItemAt(aStartIndex).getFields(); 488 489 // Loop through all the sub entry's fields and place them in the appropriate array. 490 for (var j = 0; j < aSubFields.length; j++) 491 { 492 aFormattedList[aPlacementIndex][aSubFields[j].name] = theDiscussionSet.getItemAt(aStartIndex).getField(aSubFields[j]).toString() 493 } 494 495 aPlacementIndex++; 496 497 // Descending order. 498 aLimit--; 499 if (aLimit <= 0) 500 { 501 break; 502 } 503 if (theOrder === 'desc') 504 { 505 aStartIndex--; 506 if (aStartIndex < 0) 507 { 508 break; 509 } 510 } else 511 { 512 aStartIndex++; 513 if (aStartIndex > theDiscussionSet.length - 1) 514 { 515 break; 516 } 517 } 518 } 519 } 520 521 return aFormattedList; 522 }; 523 524 /** 525 * Adds the standard response data requested by the user 526 * @param theFileOrFolder 527 * @param theJSON 528 */ 529 REST.getInfo = function(theFileOrFolder, theJSON) 530 { 531 logger.fine("file or folder: " + theFileOrFolder + " " + theJSON); 532 theJSON = !theJSON ? {} : theJSON; 533 if (fileManager.isFile(theFileOrFolder.path)) 534 { 535 theJSON.id = theFileOrFolder.assetId; 536 if (myVerbose) 537 { 538 theJSON.name = theFileOrFolder.name; 539 theJSON.path = REST.getACLRelativePath(theFileOrFolder.path); 540 theJSON.directoryId = theFileOrFolder.parent.directoryId; 541 theJSON.height = theFileOrFolder.height; 542 theJSON.width = theFileOrFolder.width; 543 theJSON.bytes = theFileOrFolder.fileSizeIncludingMetadata; 544 theJSON.lastModified = theFileOrFolder.lastModified; 545 if (!!theFileOrFolder.fileNameExtension || !!kMimeMap[theFileOrFolder.fileNameExtension.toLowerCase()]) 546 { 547 theJSON.mimeType = kMimeMap[theFileOrFolder.fileNameExtension.toLowerCase()]; 548 } else 549 { 550 logger.error("Failed to find a mimeType for the file extension: " + theFileOrFolder.fileNameExtension); 551 } 552 theJSON.previews = {}; 553 theJSON.previews.thumbnail = theFileOrFolder.getImageURL("thumbnails").replace("..", context.getServerURL()); 554 theJSON.previews.viewex = theFileOrFolder.getImageURL("viewex").replace("..", context.getServerURL()); 555 theJSON.previews.high = theFileOrFolder.getImageURL("high").replace("..", context.getServerURL()); 556 theJSON.previews.downloadUrl = context.getServerURL() + "/servlet/dload/" + theFileOrFolder.name + "?id=" + theFileOrFolder.encodedAssetId; 557 theJSON.replaceDate = theFileOrFolder.xmp.meta.getField(kReplaceDate); 558 theJSON.replaceDate = !!theJSON.replaceDate ? parseInt(theJSON.replaceDate) : 0; 559 var aVersionNumber = versionManager.getVersionCount( 560 theFileOrFolder.assetId, 561 "", 562 ["Named"] 563 ); 564 theJSON.versionNumber = !aVersionNumber || isNaN(aVersionNumber) ? 0 : parseInt(aVersionNumber); 565 var aVersionAssets = versionManager.getVersions( 566 theFileOrFolder.assetId, 567 ["Named"], 568 aVersionNumber 569 ); 570 if (!!aVersionAssets && aVersionAssets.length > 0) 571 { 572 var aVersionIds = []; 573 for (var i = 0; i < aVersionAssets.length; i++) 574 { 575 var aVersionAsset = aVersionAssets[i]; 576 aVersionIds.push(aVersionAsset.assetId); 577 } 578 theJSON.versionIds = aVersionIds; 579 } 580 } 581 582 if (myCollectDocumentReport) 583 { 584 var anExt = theFileOrFolder.fileNameExtension; 585 if (anExt == "indd" || anExt == "qxd" || anExt == "ai") 586 { 587 //check for linked assets 588 theJSON.documentLinks = []; 589 var aLinks = linkManager.getEmbeddedFiles(theFileOrFolder); 590 for (var i in aLinks) 591 { 592 var aLink = aLinks[i]; 593 theJSON.documentLinks[theJSON.documentLinks.length] = REST.getInfo(aLink.getManagedFile(), { 594 linkPath: aLink.filePath, 595 }); 596 } 597 } 598 } 599 600 if (myMtime) 601 { 602 //mtime from the db. More specific than lastModified. 603 theJSON.mtime = new SQL().queryForString("SELECT xmp_modification_db FROM editorial WHERE record_id = " + theJSON.id); 604 } 605 606 //Get fields if they were provided 607 if (!!myRequestParameters.fields && myRequestParameters.fields.length > 0) 608 { 609 theJSON.fields = {}; 610 var aFields = !Array.isArray(myRequestParameters.fields) ? [myRequestParameters.fields] : myRequestParameters.fields; 611 for (var i = 0; i < aFields.length; i++) 612 { 613 var aFieldId = aFields[i]; 614 if (!fieldManager.canView(aFieldId, context.getUser().getViewLevel())) 615 { 616 logger.warning("Cannot view: " + aFieldId); 617 continue; 618 } 619 var aProp = REST.getProperty(aFieldId); 620 var aVal; 621 if (aProp.namespace === 'database') 622 { 623 aVal = theFileOrFolder[aProp.name]; 624 if (aVal == null) 625 { 626 aVal = theFileOrFolder.getDatabaseField(aProp.name); 627 } 628 } else 629 { 630 aVal = theFileOrFolder.xmp.meta.getField(aProp); 631 if (aVal instanceof Collection) 632 { 633 var aJSONVal = []; 634 var anIterator = aVal.iterator; 635 while (anIterator.hasMore) 636 { 637 var aBlock = anIterator.next; 638 if (aBlock instanceof Resource) 639 { 640 //Build data block as a JSON object. 641 var aJSONBlock = {}; 642 var aProperties = aBlock.getFields(); 643 for (var k in aProperties) 644 { 645 var aProperty = aProperties[k]; 646 var aBlockVal = aBlock.getField(aProperty); 647 if (aBlockVal instanceof Collection) 648 { 649 aBlockVal = JSON.parse(aBlockVal); 650 } 651 aJSONBlock[aProperty.fieldId] = aBlockVal; 652 } 653 aJSONVal[aJSONVal.length] = aJSONBlock; 654 } else 655 { 656 aJSONVal[aJSONVal.length] = aBlock; 657 } 658 } 659 aVal = aJSONVal; 660 } 661 } 662 theJSON.fields[aFieldId] = aVal; 663 } 664 } 665 } else if (fileManager.isFolder(theFileOrFolder.path)) 666 { 667 theJSON = REST.buildFolderObject(theFileOrFolder, REST.getACLRelativePath(theFileOrFolder.path), false); 668 } 669 670 return theJSON; 671 }; 672 673 /** 674 * Gets all of the Parameters from the request and their values 675 * @returns {{}} 676 */ 677 function getParameters() 678 { 679 var aToIgnore = ["request.headers", "workflow.url.path"]; 680 var aRequestParameters = {}; 681 var aParameters = context.getParameterNames(); 682 for (var i in aParameters) 683 { 684 var aParamName = aParameters[i]; 685 var aParamVal = context.getParameter(aParamName); 686 if (aToIgnore.indexOf(aParameters[i]) >= 0) 687 { 688 continue; 689 } 690 if (aParamName.indexOf("MBUploadedFile") >= 0) 691 { 692 //looks like we found our selves an uploaded file 693 //add it back as its original name 694 var anOriginal = aParamName.split("MBUploadedFile").join(""); 695 var aFileObject = context.getParameter(anOriginal); 696 aRequestParameters[anOriginal] = { 697 "isFile" : true, 698 "name" : aFileObject.name, 699 "length" : aFileObject.length 700 } 701 } else 702 { 703 aRequestParameters[aParamName] = aParamVal; 704 } 705 } 706 return aRequestParameters; 707 } 708 709 /** 710 * Formats the exception 711 * @param theE 712 * @returns {string} 713 */ 714 function stack(theE) 715 { 716 return theE + (!!theE.stack ? "\n" + theE.stack : ""); 717 } 718 719 /** 720 * executes myCallback if we haven't encountered an error already. 721 * @param theCallbackParameter 722 */ 723 function errorCheckingCallback(theCallbackParameter) 724 { 725 if (REST.getStopOnFirstError() && REST.hasErrors()) 726 { 727 return; 728 } else 729 { 730 try 731 { 732 if (!!myCallback) 733 { 734 myCallback(theCallbackParameter); 735 } 736 } catch (anE) 737 { 738 var aParam = !!theCallbackParameter ? theCallbackParameter : ""; 739 aParam = !!aParam.name ? aParam.name : (typeof aParam === 'object' ? JSON.stringify(aParam) : aParam.toString()); 740 REST.pushError(REST.errors.e500, "Failed to execute " + myCallback.name + "(" + (!aParam ? "" : "'" + aParam + "'") + ");", anE); 741 } 742 } 743 } 744 745 /** 746 * Logs the request made to the REST workflow 747 */ 748 function logRequest() 749 { 750 var aToIgnore = ["request.headers"]; 751 var aToLog = {}; 752 var aParameters = context.getParameterNames(); 753 for (var i in aParameters) 754 { 755 var aParamName = aParameters[i]; 756 var aParamVal = context.getParameter(aParamName); 757 if (aToIgnore.indexOf(aParameters[i]) >= 0) 758 { 759 continue; 760 } 761 if (aParamName.indexOf("MBUploadedFile") >= 0) 762 { 763 //looks like we found our selves an uploaded file 764 //add it back as its original name 765 var anOriginal = aParamName.split("MBUploadedFile").join(""); 766 var aFileObject = context.getParameter(anOriginal); 767 aToLog[anOriginal] = { 768 "isFile" : true, 769 "name" : aFileObject.name, 770 "length" : aFileObject.length 771 } 772 } else 773 { 774 aToLog[aParamName] = aParamVal; 775 } 776 } 777 logger.config("REST API request parameters:\n " + JSON.stringify(aToLog, null, 2)); 778 } 779 780 /** 781 * Executes a search with the parameters the pageSize, pageNumber, sortDirection, and sortField 782 * @param theSearch 783 * @param theCallback the search callback 784 */ 785 REST.executeSearchWithPaging = function(theSearch) 786 { 787 var aPageSize = myRequestParameters["pageSize"]; 788 var aPageNumber = myRequestParameters["pageIndex"]; 789 var aSortDirection = myRequestParameters["sortDirection"]; 790 var aSortField = myRequestParameters["sortField"]; 791 if (!!aSortDirection && !!aSortField) 792 { 793 theSearch.setSortDirection(aSortDirection); 794 theSearch.setSortField(aSortField); 795 } 796 aPageSize = !aPageSize ? 100 : aPageSize; 797 aPageNumber = !aPageNumber ? 0 : aPageNumber; 798 return theSearch.executeForArray(aPageNumber, aPageSize) 799 }; 800 801 REST.isVerbose = function() 802 { 803 return myVerbose; 804 }; 805 806 /** 807 * Initializes the JSON object for the response 808 * @param theFolder 809 * @returns {{name: *, path: (string|void|*|XML), id: *, parentId: *, resolver: string, assets: *}} 810 */ 811 REST.buildFolderObject = function(theFolder) 812 { 813 var anAclPath = REST.getACLRelativePath(theFolder.path); 814 var aIsRoot = "/" === anAclPath; 815 var aFolder = { 816 "path": anAclPath, 817 "id": theFolder.directoryId, 818 "parentId": aIsRoot ? undefined : theFolder.parent.directoryId, 819 }; 820 if (REST.isVerbose()) 821 { 822 Object.assign(aFolder, { 823 "name" : aIsRoot ? "Index": theFolder.name, 824 "resolver" : "directory://" + theFolder.directoryId, 825 }); 826 } 827 return aFolder; 828 }; 829 830 /** 831 * Gets an array of paths of all of the directories in this acl 832 * @param theFolder 833 * @param theDepth 834 * @param theParentJSON 835 * @param theIsHierarchy return a JSON data structure with children folders nested in other folders 836 * @returns {Array} flat list of all found directories. 837 */ 838 REST.getChildDirectories = function(theFolder, theDepth, theIsHierarchy, theParentJSON) 839 { 840 theParentJSON = !!theParentJSON ? theParentJSON : REST.buildFolderObject(theFolder); 841 var aAllChildren = []; 842 if (theDepth != 0) //-1 should find all children directories 843 { 844 var aChildren = theFolder.children; 845 if (theIsHierarchy) 846 { 847 theParentJSON.children = []; 848 } 849 for (var i in aChildren) 850 { 851 var aChild = aChildren[i]; 852 if (aChild.path === "Renditions/") 853 { 854 continue; 855 } 856 var aChildJSON = REST.buildFolderObject(aChild); 857 if (theIsHierarchy) 858 { 859 theParentJSON.children.push(aChildJSON); 860 } 861 aAllChildren.push(aChildJSON); 862 var aGrandChildren = REST.getChildDirectories(aChild, theDepth - 1, theIsHierarchy, aChildJSON); 863 aAllChildren.push.apply(aAllChildren, aGrandChildren); 864 } 865 } else if (theFolder.children.length > 0) 866 { 867 theParentJSON.hasChildren = true; 868 } 869 return aAllChildren; 870 }; 871 872 /** 873 * Get facets as a JSON array from solr. 874 * 875 * @param theFieldId the field id 876 * @param thePageSize the page size 877 * @param theIncludedSearch the included search 878 * @param theHierarchyLevel the hierarchy level 879 * @param thePageNumber the page number 880 * @returns {Array} 881 */ 882 REST.getFacets = function(theFieldId, thePageSize, theIncludedSearch, theHierarchyLevel, thePageNumber) 883 { 884 theFieldId = theFieldId.replace("database ", ""); 885 var aSearch = !!theIncludedSearch ? theIncludedSearch : new Search(); 886 var aSolrConfig = new SolrConfig(); 887 888 aSolrConfig.addFacetField(theFieldId); 889 aSolrConfig.setNumberResults(theFieldId, thePageSize); 890 aSolrConfig.setHierarchyLevel(theFieldId, !!theHierarchyLevel ? theHierarchyLevel : 0); 891 892 //Return a facet map from the search 893 var aResults = []; 894 var aFacet = aSearch.getTermsWithLimit( 895 aSolrConfig, 896 !!thePageNumber ? thePageNumber : 0, 897 !!thePageSize ? thePageSize : 1000 898 ); 899 if (!!aFacet) 900 { 901 var aFacetFieldId = aFacet.getFieldId(); 902 if (aFacetFieldId == theFieldId) 903 { 904 for (var i = 0; i < aFacet.size(); i++) 905 { 906 var aFacetLabel = aFacet.getValue(i).getLabel(); 907 if (aFacetLabel != "MBFacetMissing") 908 { 909 aResults[aResults.length] = { 910 value: aFacetLabel, 911 count: aFacet.getValue(i).getCount(), 912 raw: aFacet.getValue(i).getRawLabel() 913 }; 914 } 915 } 916 } 917 } 918 return aResults; 919 }; 920 921 REST.errors = { 922 // 400 923 e400: {name: "Bad Request", code: 400}, 924 e401: {name: "Unauthorized", code: 401}, 925 e403: {name: "Forbidden", code: 403}, 926 e404: {name: "Not Found", code: 404}, 927 e405: {name: "Method Not Allowed", code: 405}, 928 e406: {name: "Not Acceptable", code: 406}, 929 e409: {name: "Conflict", code: 409}, 930 931 // 500 932 e500: {name: "Internal Server Error", code: 500}, 933 }; 934 935 return REST; 936 }; 937 938 939 /** 940 * ext to mime type mapping 941 */ 942 var kMimeMap = { 943 "x3d":"application/vnd.hzn-3d-crossword", 944 "3gp":"video/3gpp", 945 "3g2":"video/3gpp2", 946 "mseq":"application/vnd.mseq", 947 "pwn":"application/vnd.3m.post-it-notes", 948 "plb":"application/vnd.3gpp.pic-bw-large", 949 "psb":"application/vnd.3gpp.pic-bw-small", 950 "pvb":"application/vnd.3gpp.pic-bw-var", 951 "tcap":"application/vnd.3gpp2.tcap", 952 "7z":"application/x-7z-compressed", 953 "abw":"application/x-abiword", 954 "ace":"application/x-ace-compressed", 955 "acc":"application/vnd.americandynamics.acc", 956 "acu":"application/vnd.acucobol", 957 "atc":"application/vnd.acucorp", 958 "adp":"audio/adpcm", 959 "aab":"application/x-authorware-bin", 960 "aam":"application/x-authorware-map", 961 "aas":"application/x-authorware-seg", 962 "air":"application/vnd.adobe.air-application-installer-package+zip", 963 "swf":"application/x-shockwave-flash", 964 "fxp":"application/vnd.adobe.fxp", 965 "pdf":"application/pdf", 966 "ppd":"application/vnd.cups-ppd", 967 "dir":"application/x-director", 968 "xdp":"application/vnd.adobe.xdp+xml", 969 "xfdf":"application/vnd.adobe.xfdf", 970 "aac":"audio/x-aac", 971 "ahead":"application/vnd.ahead.space", 972 "azf":"application/vnd.airzip.filesecure.azf", 973 "azs":"application/vnd.airzip.filesecure.azs", 974 "azw":"application/vnd.amazon.ebook", 975 "ami":"application/vnd.amiga.ami", 976 "apk":"application/vnd.android.package-archive", 977 "cii":"application/vnd.anser-web-certificate-issue-initiation", 978 "fti":"application/vnd.anser-web-funds-transfer-initiation", 979 "atx":"application/vnd.antix.game-component", 980 "dmg":"application/x-apple-diskimage", 981 "mpkg":"application/vnd.apple.installer+xml", 982 "aw":"application/applixware", 983 "les":"application/vnd.hhe.lesson-player", 984 "swi":"application/vnd.aristanetworks.swi", 985 "s":"text/x-asm", 986 "atomcat":"application/atomcat+xml", 987 "atomsvc":"application/atomsvc+xml", 988 "atom":"application/atom+xml", 989 "xml":"application/atom+xml", 990 "ac":"application/pkix-attr-cert", 991 "aif":"audio/x-aiff", 992 "avi":"video/x-msvideo", 993 "aep":"application/vnd.audiograph", 994 "dxf":"image/vnd.dxf", 995 "dwf":"model/vnd.dwf", 996 "par":"text/plain-bas", 997 "bcpio":"application/x-bcpio", 998 "bin":"application/octet-stream", 999 "bmp":"image/bmp", 1000 "torrent":"application/x-bittorrent", 1001 "cod":"application/vnd.rim.cod", 1002 "mpm":"application/vnd.blueice.multipass", 1003 "bmi":"application/vnd.bmi", 1004 "sh":"application/x-sh", 1005 "btif":"image/prs.btif", 1006 "rep":"application/vnd.businessobjects", 1007 "bz":"application/x-bzip", 1008 "bz2":"application/x-bzip2", 1009 "csh":"application/x-csh", 1010 "c":"text/x-c", 1011 "cdxml":"application/vnd.chemdraw+xml", 1012 "css":"text/css", 1013 "cdx":"chemical/x-cdx", 1014 "cml":"chemical/x-cml", 1015 "csml":"chemical/x-csml", 1016 "cdbcmsg":"application/vnd.contact.cmsg", 1017 "cla":"application/vnd.claymore", 1018 "c4g":"application/vnd.clonk.c4group", 1019 "sub":"image/vnd.dvb.subtitle", 1020 "cdmia":"application/cdmi-capability", 1021 "cdmic":"application/cdmi-container", 1022 "cdmid":"application/cdmi-domain", 1023 "cdmio":"application/cdmi-object", 1024 "cdmiq":"application/cdmi-queue", 1025 "c11amc":"application/vnd.cluetrust.cartomobile-config", 1026 "c11amz":"application/vnd.cluetrust.cartomobile-config-pkg", 1027 "ras":"image/x-cmu-raster", 1028 "dae":"model/vnd.collada+xml", 1029 "csv":"text/csv", 1030 "cpt":"application/mac-compactpro", 1031 "wmlc":"application/vnd.wap.wmlc", 1032 "cgm":"image/cgm", 1033 "ice":"x-conference/x-cooltalk", 1034 "cmx":"image/x-cmx", 1035 "xar":"application/vnd.xara", 1036 "cmc":"application/vnd.cosmocaller", 1037 "cpio":"application/x-cpio", 1038 "clkx":"application/vnd.crick.clicker", 1039 "clkk":"application/vnd.crick.clicker.keyboard", 1040 "clkp":"application/vnd.crick.clicker.palette", 1041 "clkt":"application/vnd.crick.clicker.template", 1042 "clkw":"application/vnd.crick.clicker.wordbank", 1043 "wbs":"application/vnd.criticaltools.wbs+xml", 1044 "cryptonote":"application/vnd.rig.cryptonote", 1045 "cif":"chemical/x-cif", 1046 "cmdf":"chemical/x-cmdf", 1047 "cu":"application/cu-seeme", 1048 "cww":"application/prs.cww", 1049 "curl":"text/vnd.curl", 1050 "dcurl":"text/vnd.curl.dcurl", 1051 "mcurl":"text/vnd.curl.mcurl", 1052 "scurl":"text/vnd.curl.scurl", 1053 "car":"application/vnd.curl.car", 1054 "pcurl":"application/vnd.curl.pcurl", 1055 "cmp":"application/vnd.yellowriver-custom-menu", 1056 "dssc":"application/dssc+der", 1057 "xdssc":"application/dssc+xml", 1058 "deb":"application/x-debian-package", 1059 "uva":"audio/vnd.dece.audio", 1060 "uvi":"image/vnd.dece.graphic", 1061 "uvh":"video/vnd.dece.hd", 1062 "uvm":"video/vnd.dece.mobile", 1063 "uvu":"video/vnd.uvvu.mp4", 1064 "uvp":"video/vnd.dece.pd", 1065 "uvs":"video/vnd.dece.sd", 1066 "uvv":"video/vnd.dece.video", 1067 "dvi":"application/x-dvi", 1068 "seed":"application/vnd.fdsn.seed", 1069 "dtb":"application/x-dtbook+xml", 1070 "res":"application/x-dtbresource+xml", 1071 "ait":"application/vnd.dvb.ait", 1072 "svc":"application/vnd.dvb.service", 1073 "eol":"audio/vnd.digital-winds", 1074 "djvu":"image/vnd.djvu", 1075 "dtd":"application/xml-dtd", 1076 "mlp":"application/vnd.dolby.mlp", 1077 "wad":"application/x-doom", 1078 "dpg":"application/vnd.dpgraph", 1079 "dra":"audio/vnd.dra", 1080 "dfac":"application/vnd.dreamfactory", 1081 "dts":"audio/vnd.dts", 1082 "dtshd":"audio/vnd.dts.hd", 1083 "dwg":"image/vnd.dwg", 1084 "geo":"application/vnd.dynageo", 1085 "es":"application/ecmascript", 1086 "mag":"application/vnd.ecowin.chart", 1087 "mmr":"image/vnd.fujixerox.edmics-mmr", 1088 "rlc":"image/vnd.fujixerox.edmics-rlc", 1089 "exi":"application/exi", 1090 "mgz":"application/vnd.proteus.magazine", 1091 "epub":"application/epub+zip", 1092 "eml":"message/rfc822", 1093 "nml":"application/vnd.enliven", 1094 "xpr":"application/vnd.is-xpr", 1095 "xif":"image/vnd.xiff", 1096 "xfdl":"application/vnd.xfdl", 1097 "emma":"application/emma+xml", 1098 "ez2":"application/vnd.ezpix-album", 1099 "ez3":"application/vnd.ezpix-package", 1100 "fst":"image/vnd.fst", 1101 "fvt":"video/vnd.fvt", 1102 "fbs":"image/vnd.fastbidsheet", 1103 "fe_launch":"application/vnd.denovo.fcselayout-link", 1104 "f4v":"video/x-f4v", 1105 "flv":"video/x-flv", 1106 "fpx":"image/vnd.fpx", 1107 "npx":"image/vnd.net-fpx", 1108 "flx":"text/vnd.fmi.flexstor", 1109 "fli":"video/x-fli", 1110 "ftc":"application/vnd.fluxtime.clip", 1111 "fdf":"application/vnd.fdf", 1112 "f":"text/x-fortran", 1113 "mif":"application/vnd.mif", 1114 "fm":"application/vnd.framemaker", 1115 "fh":"image/x-freehand", 1116 "fsc":"application/vnd.fsc.weblaunch", 1117 "fnc":"application/vnd.frogans.fnc", 1118 "ltf":"application/vnd.frogans.ltf", 1119 "ddd":"application/vnd.fujixerox.ddd", 1120 "xdw":"application/vnd.fujixerox.docuworks", 1121 "xbd":"application/vnd.fujixerox.docuworks.binder", 1122 "oas":"application/vnd.fujitsu.oasys", 1123 "oa2":"application/vnd.fujitsu.oasys2", 1124 "oa3":"application/vnd.fujitsu.oasys3", 1125 "fg5":"application/vnd.fujitsu.oasysgp", 1126 "bh2":"application/vnd.fujitsu.oasysprs", 1127 "spl":"application/x-futuresplash", 1128 "fzs":"application/vnd.fuzzysheet", 1129 "g3":"image/g3fax", 1130 "gmx":"application/vnd.gmx", 1131 "gtw":"model/vnd.gtw", 1132 "txd":"application/vnd.genomatix.tuxedo", 1133 "ggb":"application/vnd.geogebra.file", 1134 "ggt":"application/vnd.geogebra.tool", 1135 "gdl":"model/vnd.gdl", 1136 "gex":"application/vnd.geometry-explorer", 1137 "gxt":"application/vnd.geonext", 1138 "g2w":"application/vnd.geoplan", 1139 "g3w":"application/vnd.geospace", 1140 "gsf":"application/x-font-ghostscript", 1141 "bdf":"application/x-font-bdf", 1142 "gtar":"application/x-gtar", 1143 "texinfo":"application/x-texinfo", 1144 "gnumeric":"application/x-gnumeric", 1145 "kml":"application/vnd.google-earth.kml+xml", 1146 "kmz":"application/vnd.google-earth.kmz", 1147 "gqf":"application/vnd.grafeq", 1148 "gif":"image/gif", 1149 "gv":"text/vnd.graphviz", 1150 "gac":"application/vnd.groove-account", 1151 "ghf":"application/vnd.groove-help", 1152 "gim":"application/vnd.groove-identity-message", 1153 "grv":"application/vnd.groove-injector", 1154 "gtm":"application/vnd.groove-tool-message", 1155 "tpl":"application/vnd.groove-tool-template", 1156 "vcg":"application/vnd.groove-vcard", 1157 "h261":"video/h261", 1158 "h263":"video/h263", 1159 "h264":"video/h264", 1160 "hpid":"application/vnd.hp-hpid", 1161 "hps":"application/vnd.hp-hps", 1162 "hdf":"application/x-hdf", 1163 "rip":"audio/vnd.rip", 1164 "hbci":"application/vnd.hbci", 1165 "jlt":"application/vnd.hp-jlyt", 1166 "pcl":"application/vnd.hp-pcl", 1167 "hpgl":"application/vnd.hp-hpgl", 1168 "hvs":"application/vnd.yamaha.hv-script", 1169 "hvd":"application/vnd.yamaha.hv-dic", 1170 "hvp":"application/vnd.yamaha.hv-voice", 1171 "sfd-hdstx":"application/vnd.hydrostatix.sof-data", 1172 "stk":"application/hyperstudio", 1173 "hal":"application/vnd.hal+xml", 1174 "html":"text/html", 1175 "irm":"application/vnd.ibm.rights-management", 1176 "sc":"application/vnd.ibm.secure-container", 1177 "ics":"text/calendar", 1178 "icc":"application/vnd.iccprofile", 1179 "ico":"image/x-icon", 1180 "icns":"image/x-icon", 1181 "cur":"image/x-icon", 1182 "igl":"application/vnd.igloader", 1183 "ief":"image/ief", 1184 "ivp":"application/vnd.immervision-ivp", 1185 "ivu":"application/vnd.immervision-ivu", 1186 "rif":"application/reginfo+xml", 1187 "3dml":"text/vnd.in3d.3dml", 1188 "spot":"text/vnd.in3d.spot", 1189 "igs":"model/iges", 1190 "i2g":"application/vnd.intergeo", 1191 "cdy":"application/vnd.cinderella", 1192 "xpw":"application/vnd.intercon.formnet", 1193 "fcs":"application/vnd.isac.fcs", 1194 "ipfix":"application/ipfix", 1195 "cer":"application/pkix-cert", 1196 "pki":"application/pkixcmp", 1197 "crl":"application/pkix-crl", 1198 "pkipath":"application/pkix-pkipath", 1199 "igm":"application/vnd.insors.igm", 1200 "rcprofile":"application/vnd.ipunplugged.rcprofile", 1201 "irp":"application/vnd.irepository.package+xml", 1202 "jad":"text/vnd.sun.j2me.app-descriptor", 1203 "jar":"application/java-archive", 1204 "class":"application/java-vm", 1205 "jnlp":"application/x-java-jnlp-file", 1206 "ser":"application/java-serialized-object", 1207 "java":"text/x-java-sourcejava", 1208 "js":"application/javascript", 1209 "json":"application/json", 1210 "joda":"application/vnd.joost.joda-archive", 1211 "jpm":"video/jpm", 1212 "jpeg":"image/jpeg", 1213 "jpe":"image/jpeg", 1214 "jpg":"image/jpeg", 1215 "pjpeg":"image/pjpeg", 1216 "jpgv":"video/jpeg", 1217 "ktz":"application/vnd.kahootz", 1218 "mmd":"application/vnd.chipnuts.karaoke-mmd", 1219 "karbon":"application/vnd.kde.karbon", 1220 "chrt":"application/vnd.kde.kchart", 1221 "kfo":"application/vnd.kde.kformula", 1222 "flw":"application/vnd.kde.kivio", 1223 "kon":"application/vnd.kde.kontour", 1224 "kpr":"application/vnd.kde.kpresenter", 1225 "ksp":"application/vnd.kde.kspread", 1226 "kwd":"application/vnd.kde.kword", 1227 "htke":"application/vnd.kenameaapp", 1228 "kia":"application/vnd.kidspiration", 1229 "kne":"application/vnd.kinar", 1230 "sse":"application/vnd.kodak-descriptor", 1231 "lasxml":"application/vnd.las.las+xml", 1232 "latex":"application/x-latex", 1233 "lbd":"application/vnd.llamagraphics.life-balance.desktop", 1234 "lbe":"application/vnd.llamagraphics.life-balance.exchange+xml", 1235 "jam":"application/vnd.jam", 1236 "123":"application/vnd.lotus-1-2-3", 1237 "apr":"application/vnd.lotus-approach", 1238 "pre":"application/vnd.lotus-freelance", 1239 "nsf":"application/vnd.lotus-notes", 1240 "org":"application/vnd.lotus-organizer", 1241 "scm":"application/vnd.lotus-screencam", 1242 "lwp":"application/vnd.lotus-wordpro", 1243 "lvp":"audio/vnd.lucent.voice", 1244 "m3u":"audio/x-mpegurl", 1245 "m4v":"video/x-m4v", 1246 "hqx":"application/mac-binhex40", 1247 "portpkg":"application/vnd.macports.portpkg", 1248 "mgp":"application/vnd.osgeo.mapguide.package", 1249 "mrc":"application/marc", 1250 "mrcx":"application/marcxml+xml", 1251 "mxf":"application/mxf", 1252 "nbp":"application/vnd.wolfram.player", 1253 "ma":"application/mathematica", 1254 "mathml":"application/mathml+xml", 1255 "mbox":"application/mbox", 1256 "mc1":"application/vnd.medcalcdata", 1257 "mscml":"application/mediaservercontrol+xml", 1258 "cdkey":"application/vnd.mediastation.cdkey", 1259 "mwf":"application/vnd.mfer", 1260 "mfm":"application/vnd.mfmp", 1261 "msh":"model/mesh", 1262 "mads":"application/mads+xml", 1263 "mets":"application/mets+xml", 1264 "mods":"application/mods+xml", 1265 "meta4":"application/metalink4+xml", 1266 "mcd":"application/vnd.mcd", 1267 "flo":"application/vnd.micrografx.flo", 1268 "igx":"application/vnd.micrografx.igx", 1269 "es3":"application/vnd.eszigno3+xml", 1270 "mdb":"application/x-msaccess", 1271 "asf":"video/x-ms-asf", 1272 "exe":"application/x-msdownload", 1273 "cil":"application/vnd.ms-artgalry", 1274 "cab":"application/vnd.ms-cab-compressed", 1275 "ims":"application/vnd.ms-ims", 1276 "application":"application/x-ms-application", 1277 "clp":"application/x-msclip", 1278 "mdi":"image/vnd.ms-modi", 1279 "eot":"application/vnd.ms-fontobject", 1280 "xls":"application/ms-excel", 1281 "xlam":"application/vnd.ms-excel.addin.macroenabled.12", 1282 "xlsb":"application/vnd.ms-excel.sheet.binary.macroenabled.12", 1283 "xltm":"application/vnd.ms-excel.template.macroenabled.12", 1284 "xlsm":"application/vnd.ms-excel.sheet.macroenabled.12", 1285 "chm":"application/vnd.ms-htmlhelp", 1286 "crd":"application/x-mscardfile", 1287 "lrm":"application/vnd.ms-lrm", 1288 "mvb":"application/x-msmediaview", 1289 "mny":"application/x-msmoney", 1290 "pptx":"application/vnd.openxmlformats-officedocument.presentationml.presentation", 1291 "sldx":"application/vnd.openxmlformats-officedocument.presentationml.slide", 1292 "ppsx":"application/vnd.openxmlformats-officedocument.presentationml.slideshow", 1293 "potx":"application/vnd.openxmlformats-officedocument.presentationml.template", 1294 "xlsx":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 1295 "xltx":"application/vnd.openxmlformats-officedocument.spreadsheetml.template", 1296 "docx":"application/vnd.openxmlformats-officedocument.wordprocessingml.document", 1297 "dotx":"application/vnd.openxmlformats-officedocument.wordprocessingml.template", 1298 "obd":"application/x-msbinder", 1299 "thmx":"application/vnd.ms-officetheme", 1300 "onetoc":"application/onenote", 1301 "pya":"audio/vnd.ms-playready.media.pya", 1302 "pyv":"video/vnd.ms-playready.media.pyv", 1303 "ppt":"application/ms-powerpoint", 1304 "pps":"application/ms-powerpoint", 1305 "ppam":"application/vnd.ms-powerpoint.addin.macroenabled.12", 1306 "sldm":"application/vnd.ms-powerpoint.slide.macroenabled.12", 1307 "pptm":"application/vnd.ms-powerpoint.presentation.macroenabled.12", 1308 "ppsm":"application/vnd.ms-powerpoint.slideshow.macroenabled.12", 1309 "potm":"application/vnd.ms-powerpoint.template.macroenabled.12", 1310 "mpp":"application/vnd.ms-project", 1311 "pub":"application/x-mspublisher", 1312 "scd":"application/x-msschedule", 1313 "xap":"application/x-silverlight-app", 1314 "stl":"application/vnd.ms-pki.stl", 1315 "cat":"application/vnd.ms-pki.seccat", 1316 "vsd":"application/vnd.visio", 1317 "vsdx":"application/vnd.visio2013", 1318 "wm":"video/x-ms-wm", 1319 "wma":"audio/x-ms-wma", 1320 "wax":"audio/x-ms-wax", 1321 "wmx":"video/x-ms-wmx", 1322 "wmd":"application/x-ms-wmd", 1323 "wpl":"application/vnd.ms-wpl", 1324 "wmz":"application/x-ms-wmz", 1325 "wmv":"video/x-ms-wmv", 1326 "wvx":"video/x-ms-wvx", 1327 "wmf":"application/x-msmetafile", 1328 "trm":"application/x-msterminal", 1329 "doc":"application/msword", 1330 "docm":"application/vnd.ms-word.document.macroenabled.12", 1331 "dotm":"application/vnd.ms-word.template.macroenabled.12", 1332 "wri":"application/x-mswrite", 1333 "wps":"application/vnd.ms-works", 1334 "xbap":"application/x-ms-xbap", 1335 "xps":"application/vnd.ms-xpsdocument", 1336 "mid":"audio/midi", 1337 "mpy":"application/vnd.ibm.minipay", 1338 "afp":"application/vnd.ibm.modcap", 1339 "rms":"application/vnd.jcp.javame.midlet-rms", 1340 "tmo":"application/vnd.tmobile-livetv", 1341 "prc":"application/x-mobipocket-ebook", 1342 "mbk":"application/vnd.mobius.mbk", 1343 "dis":"application/vnd.mobius.dis", 1344 "plc":"application/vnd.mobius.plc", 1345 "mqy":"application/vnd.mobius.mqy", 1346 "msl":"application/vnd.mobius.msl", 1347 "txf":"application/vnd.mobius.txf", 1348 "daf":"application/vnd.mobius.daf", 1349 "fly":"text/vnd.fly", 1350 "mpc":"application/vnd.mophun.certificate", 1351 "mpn":"application/vnd.mophun.application", 1352 "mj2":"video/mj2", 1353 "mpga":"audio/mpeg", 1354 "mxu":"video/vnd.mpegurl", 1355 "mpeg":"video/mpeg", 1356 "mpg":"video/mpeg", 1357 "m21":"application/mp21", 1358 "mp4a":"audio/mp4", 1359 "mp4":"video/mp4", 1360 "m4a":"video/mp4", 1361 "m4b":"video/mp4", 1362 "m4r":"video/mp4", 1363 "m4v":"video/mp4", 1364 "m3u8":"application/vnd.apple.mpegurl", 1365 "mus":"application/vnd.musician", 1366 "msty":"application/vnd.muvee.style", 1367 "mxml":"application/xv+xml", 1368 "ngdat":"application/vnd.nokia.n-gage.data", 1369 "n-gage":"application/vnd.nokia.n-gage.symbian.install", 1370 "ncx":"application/x-dtbncx+xml", 1371 "nc":"application/x-netcdf", 1372 "nlu":"application/vnd.neurolanguage.nlu", 1373 "dna":"application/vnd.dna", 1374 "nnd":"application/vnd.noblenet-directory", 1375 "nns":"application/vnd.noblenet-sealer", 1376 "nnw":"application/vnd.noblenet-web", 1377 "rpst":"application/vnd.nokia.radio-preset", 1378 "rpss":"application/vnd.nokia.radio-presets", 1379 "n3":"text/n3", 1380 "edm":"application/vnd.novadigm.edm", 1381 "edx":"application/vnd.novadigm.edx", 1382 "ext":"application/vnd.novadigm.ext", 1383 "gph":"application/vnd.flographit", 1384 "ecelp4800":"audio/vnd.nuera.ecelp4800", 1385 "ecelp7470":"audio/vnd.nuera.ecelp7470", 1386 "ecelp9600":"audio/vnd.nuera.ecelp9600", 1387 "oda":"application/oda", 1388 "ogx":"application/ogg", 1389 "oga":"audio/ogg", 1390 "ogv":"video/ogg", 1391 "ogg":"video/ogg", 1392 "dd2":"application/vnd.oma.dd2+xml", 1393 "oth":"application/vnd.oasis.opendocument.text-web", 1394 "opf":"application/oebps-package+xml", 1395 "qbo":"application/vnd.intu.qbo", 1396 "oxt":"application/vnd.openofficeorg.extension", 1397 "osf":"application/vnd.yamaha.openscoreformat", 1398 "weba":"audio/webm", 1399 "webm":"video/webm", 1400 "odc":"application/vnd.oasis.opendocument.chart", 1401 "otc":"application/vnd.oasis.opendocument.chart-template", 1402 "odb":"application/vnd.oasis.opendocument.database", 1403 "odf":"application/vnd.oasis.opendocument.formula", 1404 "odft":"application/vnd.oasis.opendocument.formula-template", 1405 "odg":"application/vnd.oasis.opendocument.graphics", 1406 "otg":"application/vnd.oasis.opendocument.graphics-template", 1407 "odi":"application/vnd.oasis.opendocument.image", 1408 "oti":"application/vnd.oasis.opendocument.image-template", 1409 "odp":"application/vnd.oasis.opendocument.presentation", 1410 "otp":"application/vnd.oasis.opendocument.presentation-template", 1411 "ods":"application/vnd.oasis.opendocument.spreadsheet", 1412 "ots":"application/vnd.oasis.opendocument.spreadsheet-template", 1413 "odt":"application/vnd.oasis.opendocument.text", 1414 "odm":"application/vnd.oasis.opendocument.text-master", 1415 "ott":"application/vnd.oasis.opendocument.text-template", 1416 "ktx":"image/ktx", 1417 "sxc":"application/vnd.sun.xml.calc", 1418 "stc":"application/vnd.sun.xml.calc.template", 1419 "sxd":"application/vnd.sun.xml.draw", 1420 "std":"application/vnd.sun.xml.draw.template", 1421 "sxi":"application/vnd.sun.xml.impress", 1422 "sti":"application/vnd.sun.xml.impress.template", 1423 "sxm":"application/vnd.sun.xml.math", 1424 "sxw":"application/vnd.sun.xml.writer", 1425 "sxg":"application/vnd.sun.xml.writer.global", 1426 "stw":"application/vnd.sun.xml.writer.template", 1427 "otf":"application/x-font-otf", 1428 "osfpvg":"application/vnd.yamaha.openscoreformat.osfpvg+xml", 1429 "dp":"application/vnd.osgi.dp", 1430 "pdb":"application/vnd.palm", 1431 "p":"text/x-pascal", 1432 "paw":"application/vnd.pawaafile", 1433 "pclxl":"application/vnd.hp-pclxl", 1434 "efif":"application/vnd.picsel", 1435 "pcx":"image/x-pcx", 1436 "psd":"image/vnd.adobe.photoshop", 1437 "prf":"application/pics-rules", 1438 "pic":"image/x-pict", 1439 "chat":"application/x-chat", 1440 "p10":"application/pkcs10", 1441 "p12":"application/x-pkcs12", 1442 "p7m":"application/pkcs7-mime", 1443 "p7s":"application/pkcs7-signature", 1444 "p7r":"application/x-pkcs7-certreqresp", 1445 "p7b":"application/x-pkcs7-certificates", 1446 "p8":"application/pkcs8", 1447 "plf":"application/vnd.pocketlearn", 1448 "pnm":"image/x-portable-anymap", 1449 "pbm":"image/x-portable-bitmap", 1450 "pcf":"application/x-font-pcf", 1451 "pfr":"application/font-tdpfr", 1452 "pgn":"application/x-chess-pgn", 1453 "pgm":"image/x-portable-graymap", 1454 "png":"image/png", 1455 "ppm":"image/x-portable-pixmap", 1456 "pskcxml":"application/pskc+xml", 1457 "pml":"application/vnd.ctc-posml", 1458 "ai":"application/postscript", 1459 "pfa":"application/x-font-type1", 1460 "pbd":"application/vnd.powerbuilder6", 1461 "pgp":"application/pgp-encrypted", 1462 "box":"application/vnd.previewsystems.box", 1463 "ptid":"application/vnd.pvi.ptid1", 1464 "pls":"application/pls+xml", 1465 "str":"application/vnd.pg.format", 1466 "ei6":"application/vnd.pg.osasli", 1467 "dsc":"text/prs.lines.tag", 1468 "psf":"application/x-font-linux-psf", 1469 "qps":"application/vnd.publishare-delta-tree", 1470 "wg":"application/vnd.pmi.widget", 1471 "qxd":"application/vnd.quark.quarkxpress", 1472 "esf":"application/vnd.epson.esf", 1473 "msf":"application/vnd.epson.msf", 1474 "ssf":"application/vnd.epson.ssf", 1475 "qam":"application/vnd.epson.quickanime", 1476 "qfx":"application/vnd.intu.qfx", 1477 "qt":"video/quicktime", 1478 "rar":"application/x-rar-compressed", 1479 "ram":"audio/x-pn-realaudio", 1480 "rmp":"audio/x-pn-realaudio-plugin", 1481 "rsd":"application/rsd+xml", 1482 "rm":"application/vnd.rn-realmedia", 1483 "ra":"application/vnd.rn-realmedia", 1484 "rv":"application/vnd.rn-realmedia", 1485 "bed":"application/vnd.realvnc.bed", 1486 "mxl":"application/vnd.recordare.musicxml", 1487 "musicxml":"application/vnd.recordare.musicxml+xml", 1488 "rnc":"application/relax-ng-compact-syntax", 1489 "rdz":"application/vnd.data-vision.rdz", 1490 "rdf":"application/rdf+xml", 1491 "rp9":"application/vnd.cloanto.rp9", 1492 "jisp":"application/vnd.jisp", 1493 "rtf":"application/rtf", 1494 "rtx":"text/richtext", 1495 "link66":"application/vnd.route66.link66+xml", 1496 "rss":"application/rss+xml", 1497 "shf":"application/shf+xml", 1498 "st":"application/vnd.sailingtracker.track", 1499 "svg":"image/svg+xml", 1500 "svgz":"image/svg+xml", 1501 "sus":"application/vnd.sus-calendar", 1502 "sru":"application/sru+xml", 1503 "setpay":"application/set-payment-initiation", 1504 "setreg":"application/set-registration-initiation", 1505 "sema":"application/vnd.sema", 1506 "semd":"application/vnd.semd", 1507 "semf":"application/vnd.semf", 1508 "see":"application/vnd.seemail", 1509 "snf":"application/x-font-snf", 1510 "spq":"application/scvp-vp-request", 1511 "spp":"application/scvp-vp-response", 1512 "scq":"application/scvp-cv-request", 1513 "scs":"application/scvp-cv-response", 1514 "sdp":"application/sdp", 1515 "etx":"text/x-setext", 1516 "movie":"video/x-sgi-movie", 1517 "ifm":"application/vnd.shana.informed.formdata", 1518 "itp":"application/vnd.shana.informed.formtemplate", 1519 "iif":"application/vnd.shana.informed.interchange", 1520 "ipk":"application/vnd.shana.informed.package", 1521 "tfi":"application/thraud+xml", 1522 "shar":"application/x-shar", 1523 "rgb":"image/x-rgb", 1524 "slt":"application/vnd.epson.salt", 1525 "aso":"application/vnd.accpac.simply.aso", 1526 "imp":"application/vnd.accpac.simply.imp", 1527 "twd":"application/vnd.simtech-mindmapper", 1528 "csp":"application/vnd.commonspace", 1529 "saf":"application/vnd.yamaha.smaf-audio", 1530 "mmf":"application/vnd.smaf", 1531 "spf":"application/vnd.yamaha.smaf-phrase", 1532 "teacher":"application/vnd.smart.teacher", 1533 "svd":"application/vnd.svd", 1534 "rq":"application/sparql-query", 1535 "srx":"application/sparql-results+xml", 1536 "gram":"application/srgs", 1537 "grxml":"application/srgs+xml", 1538 "ssml":"application/ssml+xml", 1539 "skp":"application/vnd.koan", 1540 "sgml":"text/sgml", 1541 "sdc":"application/vnd.stardivision.calc", 1542 "sda":"application/vnd.stardivision.draw", 1543 "sdd":"application/vnd.stardivision.impress", 1544 "smf":"application/vnd.stardivision.math", 1545 "sdw":"application/vnd.stardivision.writer", 1546 "sgl":"application/vnd.stardivision.writer-global", 1547 "sm":"application/vnd.stepmania.stepchart", 1548 "sit":"application/x-stuffit", 1549 "sitx":"application/x-stuffitx", 1550 "sdkm":"application/vnd.solent.sdkm+xml", 1551 "xo":"application/vnd.olpc-sugar", 1552 "au":"audio/basic", 1553 "wqd":"application/vnd.wqd", 1554 "sis":"application/vnd.symbian.install", 1555 "smi":"application/smil+xml", 1556 "xsm":"application/vnd.syncml+xml", 1557 "bdm":"application/vnd.syncml.dm+wbxml", 1558 "xdm":"application/vnd.syncml.dm+xml", 1559 "sv4cpio":"application/x-sv4cpio", 1560 "sv4crc":"application/x-sv4crc", 1561 "sbml":"application/sbml+xml", 1562 "tsv":"text/tab-separated-values", 1563 "tif":"image/tiff", 1564 "tiff":"image/tiff", 1565 "tao":"application/vnd.tao.intent-module-archive", 1566 "tar":"application/x-tar", 1567 "tcl":"application/x-tcl", 1568 "tex":"application/x-tex", 1569 "tfm":"application/x-tex-tfm", 1570 "tei":"application/tei+xml", 1571 "txt":"text/plain", 1572 "dxp":"application/vnd.spotfire.dxp", 1573 "sfs":"application/vnd.spotfire.sfs", 1574 "tsd":"application/timestamped-data", 1575 "tpt":"application/vnd.trid.tpt", 1576 "mxs":"application/vnd.triscape.mxs", 1577 "t":"text/troff", 1578 "tra":"application/vnd.trueapp", 1579 "ttf":"application/x-font-ttf", 1580 "ttl":"text/turtle", 1581 "umj":"application/vnd.umajin", 1582 "uoml":"application/vnd.uoml+xml", 1583 "unityweb":"application/vnd.unity", 1584 "ufd":"application/vnd.ufdl", 1585 "uri":"text/uri-list", 1586 "utz":"application/vnd.uiq.theme", 1587 "ustar":"application/x-ustar", 1588 "uu":"text/x-uuencode", 1589 "vcs":"text/x-vcalendar", 1590 "vcf":"text/x-vcard", 1591 "vcd":"application/x-cdlink", 1592 "vsf":"application/vnd.vsf", 1593 "wrl":"model/vrml", 1594 "vcx":"application/vnd.vcx", 1595 "mts":"model/vnd.mts", 1596 "vtu":"model/vnd.vtu", 1597 "vis":"application/vnd.visionary", 1598 "viv":"video/vnd.vivo", 1599 "ccxml":"application/ccxml+xml", 1600 "vxml":"application/voicexml+xml", 1601 "src":"application/x-wais-source", 1602 "wbxml":"application/vnd.wap.wbxml", 1603 "wbmp":"image/vnd.wap.wbmp", 1604 "wav":"audio/x-wav", 1605 "davmount":"application/davmount+xml", 1606 "woff":"application/x-font-woff", 1607 "wspolicy":"application/wspolicy+xml", 1608 "webp":"image/webp", 1609 "wtb":"application/vnd.webturbo", 1610 "wgt":"application/widget", 1611 "hlp":"application/winhlp", 1612 "wml":"text/vnd.wap.wml", 1613 "wmls":"text/vnd.wap.wmlscript", 1614 "wmlsc":"application/vnd.wap.wmlscriptc", 1615 "wpd":"application/vnd.wordperfect", 1616 "stf":"application/vnd.wt.stf", 1617 "wsdl":"application/wsdl+xml", 1618 "xbm":"image/x-xbitmap", 1619 "xpm":"image/x-xpixmap", 1620 "xwd":"image/x-xwindowdump", 1621 "der":"application/x-x509-ca-cert", 1622 "fig":"application/x-xfig", 1623 "xhtml":"application/xhtml+xml", 1624 "xdf":"application/xcap-diff+xml", 1625 "xenc":"application/xenc+xml", 1626 "xer":"application/patch-ops-error+xml", 1627 "rl":"application/resource-lists+xml", 1628 "rs":"application/rls-services+xml", 1629 "rld":"application/resource-lists-diff+xml", 1630 "xslt":"application/xslt+xml", 1631 "xop":"application/xop+xml", 1632 "xpi":"application/x-xpinstall", 1633 "xspf":"application/xspf+xml", 1634 "xul":"application/vnd.mozilla.xul+xml", 1635 "xyz":"chemical/x-xyz", 1636 "yaml":"text/yaml", 1637 "yang":"application/yang", 1638 "yin":"application/yin+xml", 1639 "zir":"application/vnd.zul", 1640 "zip":"application/zip", 1641 "zmm":"application/vnd.handheld-entertainment+xml", 1642 "zaz":"application/vnd.zzazz.deck+xml", 1643 "xmp":"application/octet-stream", 1644 "mov":"video/quicktime", 1645 "ini":"text/plain", 1646 "mp3":"audio/x-mpeg" 1647 }; 1648