1 /* 2 * This is system cordova_plugin (TV specific API). 3 * Apache License (2004). See http://www.apache.org/licenses/LICENSE-2.0 4 * 5 * Copyright (c) 2014, LG Electronics, Inc. 6 */ 7 8 9 /** 10 * This represents the FileManager API itself, and provides a global namespace for operating FileManager service. 11 * FileManager will be used to manage files in internal memory. 12 * 13 * To locate a resource for file system APIs, SCAP URI is used. 14 * SCAP URI has following format. 15 * 16 * @class 17 */ 18 19 cordova.define('cordova/plugin/storage', function (require, exports, module) { // jshint ignore:line 20 var service; 21 function log(msg) { 22 // //console.log//will be removed // jshint ignore:line 23 } 24 if (window.PalmSystem) { // jshint ignore:line 25 log("Window.PalmSystem Available"); 26 service = require('cordova/plugin/webos/service'); 27 } 28 else { 29 service = { 30 Request: function (uri, params) { 31 log(uri + " invoked. But I am a dummy because PalmSystem is not available"); 32 if (typeof params.onFailure === 'function') { 33 params.onFailure({ 34 returnValue: false, 35 errorText: "PalmSystem Not Available. Cordova is not installed?" 36 }); 37 } 38 } 39 }; 40 } 41 42 function isValidFileURI(uri) { 43 if (uri) { 44 if (uri.indexOf("://") === -1) { 45 log("INVALID URI" + uri); 46 return false; 47 } else { 48 log("GOOD URI"); 49 return true; 50 } 51 } else { 52 log("NO URI" + uri); 53 return false; 54 } 55 } 56 57 58 /** 59 * storage interface 60 */ 61 var Storage = function () { 62 }; 63 64 /** 65 * @namespace Error 66 */ 67 Error.ERROR_CODE = { 68 /** 69 * There was an error while doing a file IO. 70 * @since 1.3 71 * @constant 72 */ 73 IO_ERROR: "IO_ERROR", 74 75 /** 76 * There was an error while accessing external storage devices. 77 * @since 1.3 78 * @constant 79 */ 80 DEVICE_ERROR: "DEVICE_ERROR", 81 82 /** 83 * The input parameter has error. 84 * @since 1.3 85 * @constant 86 */ 87 BAD_PARAMETER: "BAD_PARAMETER", 88 89 /** 90 * The remote server returned error. 91 * @since 1.3 92 * @constant 93 */ 94 SERVER_ERROR: "SERVER_ERROR", 95 96 /** 97 * The network has error connecting to the remote site. 98 * @since 1.3 99 * @constant 100 */ 101 NETWORK_ERROR: "NETWORK_ERROR", 102 103 /** 104 * The signage monitor system had error while executing the command. 105 * @since 1.3 106 * @constant 107 */ 108 SYSTEM_ERROR: "SYSTEM_ERROR", 109 }; 110 111 /** 112 * <p> 113 * This section describes the SCAP URI to locate resources for the SCAP strorage APIs. 114 * SCAP URI follows the syntax of a standard URI. 115 * </p> 116 * <p> 117 * Those restrictions are applied to the SCAP URI. 118 * <ul> 119 * <li> If the protocol for the URI is file://, then allowd charecter sets are [a-zA-Z0-9-._]</li> 120 * <li> URI cannot be longer than a 256 length string </li> 121 * </ul> 122 * </p> 123 * 124 * Those are formats that are recognized by SCAP storage APIs. 125 * <p> 126 * <div align=left> 127 * <table class="hcap_spec" width=400> 128 * <thead><tr><th>Name</th><th>Description</th></tr></thead> 129 * <tbody> 130 * <tr> 131 * <th>file://internal/</th> 132 * <th> 133 * Locate to a file in internal memory space. No directories or files should be included in the path beyond root path.<br> 134 * If the path to the file destination is not found, directories for the file path will be automatically created.<br> 135 * Maximum length for a pathname is 255. 136 * <p>(note: ../ is not allowed in the file path. '*' and '?' are also not supported.)</p> 137 * </th> 138 * </tr> 139 * <tr class="odd"> 140 * <th>file://usb:[index]/</th> 141 * <th> 142 * Locate to a file in USB storage device at USB port:[index]. A USB storage device should be connected to the port.<br> 143 * If the path to the file destination is not found, directories for the file path will be automatically created.<br> 144 * Maximum length for a pathname is 255. 145 * <p>(note: ../ is not allowed in the file path. '*' and '?' are also not supported.)</p> 146 * </th> 147 * </tr> 148 * <tr> 149 * <th>file://sdcard:[index]/</th> 150 * <th> 151 * Locate to a file in SD card device at SD card port:[index]. A SD card storage device should be connected to the port.<br> 152 * If the path to the file destination is not found, directories for the file path will be automatically created.<br> 153 * Maximum length for a pathname is 255. 154 * <p>(note: ../ is not allowed in the file path. '*' and '?' are also not supported.)</p> 155 * </th> 156 * </tr> 157 * <tr class="odd"> 158 * <th>http://, https://</th> 159 * <th> 160 * Locate to a file in remote location. The file is downloaded using HTTP GET protocol. 161 * Secure connection using https protocol is also supported. 162 * </th> 163 * </tr> 164 * <tr> 165 * <th> 166 * ftp:// (FTP)<br> 167 * sftp:// (FTP with SSH file transfer protocol)<br> 168 * ftps:// (FTP over SSL/TLS)<br> 169 * </th> 170 * <th> 171 * Locate to a file from FTP server. sftp (FTP with SSH file transfer) and ftps (FTP with SSL/TLS) is also supported.</br> 172 * Additional security option may be defined for sftp and ftps.</br> 173 * User name, password should be part of the URI if needed. </br> 174 * ex) ftp://user:password@my.ftp.site:21/path/to/file.txt 175 * If port number is not defined in URI, port number will be 21 (ftp or ftps) or 22 (sftp). </br> 176 * If auth is not defined in URI, 'anonymous:anonymous@' will be used if protocol is ftp/ftps. </br> 177 * </th> 178 * </tr> 179 * </tbody> 180 * </table> 181 * </div> 182 * </p> 183 * 184 * Note : Copied files can be accessed by local/USB application from the "./content" directory of the local/USB application</br> 185 * Note : Copied files can be accessed from local http file server.(http://127.0.0.1:9080/[copied_filename]) </br> 186 * Note : Files that are copied to USB storage can be accessed from the local http file server.(http://127.0.0.1:9080/external/usb/[usb_port]) </br> 187 * TIP : If DNS server is not set in the monitor, accessing local file server using 'localhost' can take a long time to load the resource. 188 * Use '127.0.0.1' instead. 189 * 190 * @namespace Storage.SCAP_URI 191 * @typedef string 192 */ 193 Storage.SCAP_URI = ""; 194 195 /** 196 * Maximum buffer length for readFile/writeFile (10K) 197 * @constant 198 */ 199 Storage.MAX_BUFFER_LENGTH = 1024 * 10; 200 201 /** 202 * @namespace Storage.AppMode 203 */ 204 Storage.AppMode = { 205 /** 206 * USB 207 * @since 1.1 208 * @constant 209 */ 210 USB: "usb", 211 /** 212 * local 213 * @since 1.1 214 * @constant 215 */ 216 LOCAL: "local" 217 }; 218 219 220 /** 221 * @namespace Storage.AppType 222 */ 223 Storage.AppType = { 224 /** 225 * IPK App 226 * @since 1.4.1 227 * @constant 228 */ 229 IPK: "ipk", 230 /** 231 * ZIP App 232 * @since 1.4.1 233 * @constant 234 */ 235 ZIP: "zip" 236 }; 237 /** 238 * <p> 239 * Downloads firmware from remote server using 'http' or 'https' protocol. 240 * Before downloading, check the free storage size of the platform using Storage.getStorageInfo(). <br> 241 * Received firmware file will be deleted after upgrade is completed by calling Storage.upgradeFirmware(), which in turn results in monitor reboot. <br> 242 * After reboot, stored firmware file will be deleted even if Storage.upgradeFirmware() was not called, so if wrong firmware file was downloaded, 243 * just reboot the monitor without calling Storage.upgradeFirmware() to delete it. 244 * </p> 245 * 246 * @example 247 * 248 * function downloadFirmware() { 249 * var successCb = function () { 250 * console.log("Download firmware is successful"); 251 * }; 252 * 253 * var failureCb = function(cbObject) { 254 * var errorCode = cbObject.errorCode; 255 * var errorText = cbObject.errorText; 256 * console.log( " Error Code [" + errorCode + "]: " + errorText); 257 * }; 258 * 259 * var options = { 260 * uri : "http://example.org/firmware.10-01.00.10_usb_V3_SECURED.epk" 261 * }; 262 * 263 * var storage = new Storage(); 264 * storage.downloadFirmware(successCb, failureCb, options); 265 * 266 * } 267 * 268 * 269 * @class storage 270 * @param {Function} 271 * successCallback success callback function. 272 * @param {Function} 273 * errorCallback failure callback function. 274 * @param {Object} options 275 * <div align=left> 276 * <table class="hcap_spec" width=400> 277 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 278 * <tbody> 279 * <tr><th>uri</th><th>String</th><th>URI for the firmware(in http or https)</a></th><th>required</th></tr> 280 * </tbody> 281 * </table> 282 * </div> 283 * @returns 284 * <p> 285 * After the method is successfully executed, successCallback is called without any parameter.</br> 286 * If an error occurs, errorCallback is called with errorCode and errorText as parameters. 287 * </p> 288 * @since 1.2 289 * @see 290 * <a href="Storage%23upgradeFirmware.html">Storage.upgradeFirmware()</a>, 291 * <a href="Storage%23getFirmwareUpgradeStatus.html">Storage.getFirmwareUpgradeStatus()</a><br> 292 */ 293 Storage.prototype.downloadFirmware = function (successCallback, errorCallback, options) { 294 295 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 296 method: "downloadFirmware", 297 parameters: { 298 uri: options.uri 299 }, 300 onSuccess: function (result) { 301 if (result.returnValue === true) { 302 successCallback(); 303 } 304 else { 305 errorCallback({ 306 errorCode: result.errorCode, 307 errorText: result.errorText 308 }); 309 } 310 }, 311 onFailure: function (result) { 312 errorCallback({ 313 errorCode: result.errorCode, 314 errorText: result.errorText 315 }); 316 } 317 }); 318 }; 319 320 /** 321 * <p> 322 * Upgrades firmware using stored file which was downloaded by calling Storage.downloadFirmware(). 323 * If upgrade is successful, the monitor will restart automatically. 324 * 325 * </p> 326 * 327 * @example 328 * 329 * function upgradeFirmware() { 330 * var successCb = function () { 331 * console.log("firmware upgrade is successful"); 332 * }; 333 * 334 * var failureCb = function(cbObject) { 335 * var errorCode = cbObject.errorCode; 336 * var errorText = cbObject.errorText; 337 * console.log( " Error Code [" + errorCode + "]: " + errorText); 338 * }; 339 * 340 * var storage = new Storage(); 341 * storage.upgradeFirmware(successCb, failureCb); 342 * } 343 * 344 * @class storage 345 * @param {Function} 346 * successCallback success callback function. 347 * @param {Function} 348 * errorCallback failure callback function. 349 * @returns 350 * <p> 351 * After the method is successfully executed, successCallback is called without any parameter.</br> 352 * If an error occurs, errorCallback is called with errorCode and errorText as parameters. 353 * </p> 354 * @since 1.2 355 * @see 356 * <a href="Storage%23downloadFirmware.html">Storage.downloadFirmware()</a>, <a href="Storage%23getFirmwareUpgradeStatus.html">Storage.getFirmwareUpgradeStatus()</a><br> 357 */ 358 Storage.prototype.upgradeFirmware = function (successCallback, errorCallback) { 359 360 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 361 method: "upgradeFirmware", 362 parameters: {}, 363 onSuccess: function (result) { 364 if (result.returnValue === true) { 365 successCallback(); 366 } 367 else { 368 errorCallback({ 369 errorCode: result.errorCode, 370 errorText: result.errorText 371 }); 372 } 373 }, 374 onFailure: function (result) { 375 errorCallback({ 376 errorCode: result.errorCode, 377 errorText: result.errorText 378 }); 379 } 380 }); 381 }; 382 383 /** 384 * <p> 385 * Gets the status of firmware upgrading. 386 * 387 * </p> 388 * 389 * @example 390 * 391 * function getFirmwareUpgradeStatus() { 392 * var successCb = function (cbObject) { 393 * console.log("status " + cbObject.status); 394 * console.log("upgradeProgress " + cbObject.upgradeProgress); 395 * console.log("downloadProgress " + cbObject.downloadProgress); 396 * }; 397 * 398 * var failureCb = function(cbObject) { 399 * var errorCode = cbObject.errorCode; 400 * var errorText = cbObject.errorText; 401 * console.log( " Error Code [" + errorCode + "]: " + errorText); 402 * }; 403 * 404 * var storage = new Storage(); 405 * storage.getFirmwareUpgradeStatus(successCb, failureCb); 406 * 407 * } 408 * 409 * @class storage 410 * @param {Function} 411 * successCallback success callback function. 412 * @param {Function} 413 * errorCallback failure callback function. 414 * @return {Object} 415 * <div align=left> 416 * <table class="hcap_spec" width=400> 417 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 418 * <tbody> 419 * <tr><th>status</th><th>String</th><th>idle | downloading | ready | in progress | completed | fail</a></th></tr> 420 * <tr class="odd"><th>downloadProgress</th><th>Number</th><th> 0 ~ 100 </a></th></tr> 421 * <th>upgradeProgress</th><th>Number</th><th> 0 ~ 100 </a></th></tr> 422 * </tbody> 423 * </table> 424 * </div> 425 * @since 1.2 426 * @see 427 * <a href="Storage%23downloadFirmware.html">Storage.downloadFirmware()</a>, 428 * <a href="Storage%23upgradeFirmware.html">Storage.upgradeFirmware()</a></br> 429 */ 430 Storage.prototype.getFirmwareUpgradeStatus = function (successCallback, errorCallback) { 431 432 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 433 method: "getFirmwareUpgradeStatus", 434 parameters: {}, 435 onSuccess: function (result) { 436 if (result.returnValue === true) { 437 successCallback({ 438 status: result.status, 439 upgradeProgress: result.upgradeProgress, 440 downloadProgress: result.downloadProgress 441 }); 442 } 443 else { 444 errorCallback({ 445 errorCode: result.errorCode, 446 errorText: result.errorText 447 }); 448 } 449 }, 450 onFailure: function (result) { 451 errorCallback({ 452 errorCode: result.errorCode, 453 errorText: result.errorText 454 }); 455 } 456 }); 457 }; 458 459 /** 460 * <p> 461 * Changes monitor logo image. Image can be loaded from internal|USB memory, or retrieved from remote server using 'http' or 'https'. 462 * Logo image has following restrictions : <br> 463 * - format : JPG or BMP <br> 464 * - max resolution : 1920x1080 <br> 465 * - max file size : 8 Mbytes for BMP <br> 466 * </p> 467 * 468 * @example 469 * 470 * function changeLogoImage() { 471 * var successCb = function () { 472 * console.log("Upgrading logo image is successful"); 473 * }; 474 * 475 * var failureCb = function(cbObject) { 476 * var errorCode = cbObject.errorCode; 477 * var errorText = cbObject.errorText; 478 * console.log( " Error Code [" + errorCode + "]: " + errorText); 479 * }; 480 * 481 * var options = { 482 * uri : "http://example.org/myImage.jpg" 483 * }; 484 * 485 * var storage = new Storage(); 486 * storage.changeLogoImage(successCb, failureCb, options); 487 * 488 * } 489 * 490 * @class storage 491 * @param {Function} 492 * successCallback success callback function. 493 * @param {Function} 494 * errorCallback failure callback function. 495 * @param {Object} options 496 * <div align=left> 497 * <table class="hcap_spec" width=400> 498 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 499 * <tbody> 500 * <tr><th>uri</th><th>String</th><th>URI for the logo image(http, https, file://internal or file://usb:[index])</a></th><th>required</th></tr> 501 * </tbody> 502 * </table> 503 * </div> 504 * @returns 505 * <p> 506 * After the method is successfully executed, successCallback is called without any parameter.</br> 507 * If an error occurs, errorCallback is called with errorCode and errorText as parameters. 508 * </p> 509 * @since 1.2 510 * @see 511 * <a href="Storage%23upgradeFirmware.html">Storage.upgradeFirmware()</a><br> 512 */ 513 Storage.prototype.changeLogoImage = function (successCallback, errorCallback, options) { 514 515 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 516 method: "changeLogoImage", 517 parameters: { 518 uri: options.uri 519 }, 520 onSuccess: function (result) { 521 if (result.returnValue === true) { 522 successCallback(); 523 } 524 else { 525 errorCallback({ 526 errorCode: result.errorCode, 527 errorText: result.errorText 528 }); 529 } 530 }, 531 onFailure: function (result) { 532 errorCallback({ 533 errorCode: result.errorCode, 534 errorText: result.errorText 535 }); 536 } 537 }); 538 }; 539 540 /** 541 * <p> 542 * Upgrades application stored in local or USB using the one from remote server. 543 * Remote server information(serverIP and serverPort) is set in display menu.<br> 544 * New application will be launched at next boot time and old application will be deleted at the same time. 545 * Application on the server should be at <br> 546 * "http://serverIP:serverPort/procentric/scap/application/scap_app.zip". 547 * <br> 548 * Note : Size of scap_app.zip (zip file itself and extracted files) should not exceed free storage size of the platform.<br> 549 * When application is being upgraded, following files exist at the same time : <br> 550 * - old application <br> 551 * - downloaded scap_app.zip <br> 552 * - content data stored by storage.copyFile() API and <br> 553 * - new application extracted from the downloaded scap_app.zip <br> 554 * So before upgrading the application, call storage.getStorageInfo() and check the free storage size. <br> 555 * <br> 556 * Note : Application should not include 'content' directory under application's root folder. <br> 557 * (It is reserved for Storage.copyFile() API.) 558 * 559 * </p> 560 * 561 * @example 562 * 563 * function upgradeApplication() { 564 * var successCb = function (cbObject) { 565 * console.log("Application Update successful"); 566 * }; 567 * 568 * var failureCb = function(cbObject) { 569 * var errorCode = cbObject.errorCode; 570 * var errorText = cbObject.errorText; console.log( " Error Code [" + errorCode + "]: " + errorText); 571 * }; 572 * 573 * var options = { 574 * to : Storage.AppMode.USB, 575 * recovery : false 576 * }; 577 * 578 * var storage = new Storage(); 579 * storage.upgradeApplication(successCb, failureCb, options); 580 * } 581 * 582 * @class storage 583 * @param {Function} 584 * successCallback success callback function. 585 * @param {Function} 586 * errorCallback failure callback function. 587 * @param {Object} options 588 * <div align=left> 589 * <table class="hcap_spec" width=400> 590 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 591 * <tbody> 592 * <tr><th>to</th><th>String</th><th><a href="Storage.AppMode.html#constructor">Storage.AppMode</a></th><th>required</th></tr> 593 * <tr><th>type</th><th>String</th><th><a href="Storage.AppType.html#constructor">Storage.AppType</a><br>if there is no value, it will use application type value of 8080 server ui</th><th>optional</th></tr> 594 * <tr class="odd"><tr><th>recovery</th><th>Boolean</th><th>true : Recover old application if there was an error during upgrade. Default value.<br> 595 * false : Remove old application to obtain free storage space.</a></th><th>optional</th></tr> 596 * 597 * </tbody> 598 * </table> 599 * </div> 600 * @returns 601 * <p> 602 * After the method is successfully executed, successCallback is called without any parameter.</br> 603 * If an error occurs, errorCallback is called with errorCode and errorText. 604 * </p> 605 * @since 1.0 606 * @since 1.1 options.to options.recovery added 607 * @see 608 * <a href="Storage%23removeApplication.html">Storage.removeApplication()</a><br> 609 */ 610 Storage.prototype.upgradeApplication = function (successCallback, errorCallback, options) { 611 612 var param = { 613 from: 'remote', 614 to: (options === undefined || options === null ? Storage.AppMode.LOCAL : options.to), 615 recovery: (options === undefined || options === null ? false : options.recovery), 616 }; 617 618 if(options.hasOwnProperty('type') === true && options.type !== undefined) 619 param.type = options.type; 620 621 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 622 method: "upgradeApplication", 623 parameters: param, 624 onSuccess: function (result) { 625 if (result.returnValue === true) { 626 successCallback(); 627 } 628 else { 629 errorCallback({ 630 errorCode: result.errorCode, 631 errorText: result.errorText 632 }); 633 } 634 }, 635 onFailure: function (result) { 636 errorCallback({ 637 errorCode: result.errorCode, 638 errorText: result.errorText 639 }); 640 } 641 }); 642 643 }; 644 645 /** 646 * <p> 647 * Removes application stored in local or USB storage.<br> 648 * 649 * Current running application can't remove itself using this API.<br> 650 * (e.g. Application running from USB cannot remove itself using this API) 651 * 652 * </p> 653 * 654 * @example 655 * 656 * function removeApplication() { 657 * var successCb = function (cbObject) { 658 * console.log("Application removes successfully"); 659 * }; 660 * 661 * var failureCb = function(cbObject) { 662 * var errorCode = cbObject.errorCode; 663 * var errorText = cbObject.errorText; 664 * console.log( " Error Code [" + errorCode + "]: " + errorText); 665 * }; 666 * 667 * var options = { 668 * to : Storage.AppMode.LOCAL 669 * }; 670 * 671 * var storage = new Storage(); 672 * storage.removeApplication(successCb, failureCb, options); 673 * } 674 * 675 * @class storage 676 * @param {Function} 677 * successCallback success callback function. 678 * @param {Function} 679 * errorCallback failure callback function. 680 * @param {Object} options 681 * <div align=left> 682 * <table class="hcap_spec" width=400> 683 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 684 * <tbody> 685 * <tr><th>to</th><th>String</th><th><a href="Storage.AppMode.html#constructor">Storage.AppMode</a></th><th>required</th></tr> 686 * </tbody> 687 * </table> 688 * </div> 689 * @returns 690 * <p> 691 * After the method is successfully executed, successCallback is called without any parameter.</br> 692 * If an error occurs, errorCallback is called with errorCode and errorText. 693 * </p> 694 * @since 1.1 695 * @see 696 * <a href="Storage%23upgradeApplication.html">Storage.upgradeApplication()</a><br> 697 */ 698 699 Storage.prototype.removeApplication = function (successCallback, errorCallback, options) { 700 701 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 702 method: "removeApplication", 703 parameters: { 704 to: options.to 705 }, 706 onSuccess: function (result) { 707 if (result.returnValue === true) { 708 successCallback(); 709 } else { 710 errorCallback({ 711 errorCode: result.errorCode, 712 errorText: result.errorText 713 }); 714 } 715 }, 716 onFailure: function (result) { 717 errorCallback({ 718 errorCode: result.errorCode, 719 errorText: result.errorText 720 }); 721 } 722 }); 723 }; 724 725 726 /** 727 * <p> 728 * Copies file. 729 * File can be copied from internal, external memory, or remote site to internal, external memory, or a remote FTP site.</br> 730 * </p> 731 * 732 * @example 733 * 734 * function copyFile() { 735 * var successCb = function (){ 736 * console.log("Copying File done."); 737 * }; 738 * 739 * var failureCb = function(cbObject){ 740 * var errorCode = cbObject.errorCode; 741 * var errorText = cbObject.errorText; 742 * console.log( " Error Code [" + errorCode + "]: " + errorText); 743 * }; 744 * 745 * // Copy local file in internal memory to another location in internal memory. 746 * var options_local_to_local = { 747 * source: 'file://internal/copy_me.txt', 748 * destination : 'file://internal/copy/to/here.txt' 749 * }; 750 * 751 * var storage = new Storage(); 752 * storage.copyFile(successCb, failureCb, options_local_to_local); 753 * 754 * // Copy remote file to internal memory. 755 * // Then set the file as he source for an image tag. 756 * var options_remote_to_local = { 757 * source : 'http://remote.file.site/copy_me.txt', 758 * destination : 'file://internal/copy/to/here.txt' 759 * }; 760 * 761 * storage.copyFile(successCb, failureCb, options_remote_to_local); 762 * 763 * // Copy file from USB memory at port 1 to internal memory. 764 * var options_usb_to_local = { 765 * source : 'file://usb:1/from/copy_me.txt', 766 * destination : 'file://internal/copy/to/here.txt' 767 * }; 768 * 769 * storage.copyFile( 770 * function() { // Success Call back. Set the copied file as image source. 771 * var imgElement = document.getElementById('myImage'); 772 * imgElement.src = 'http://127.0.0.1:9080/copy/to/here.jpg'; 773 * }, 774 * failureCb, options_usb_to_local); 775 * 776 * // download remote file and copy to USB storage at port 1. 777 * // Then set the file as he source for an image tag. 778 * var options_remote_to_usb = { 779 * source : 'http://remote.file.site/copy_me.jpg', 780 * destination : 'file://usb:1/copy/to/here.jpg' 781 * }; 782 * 783 * storage.copyFile( 784 * function() { // Success Call back. Set the copied file as image source. 785 * var imgElement = document.getElementById('myImage'); 786 * imgElement.src = 'http://127.0.0.1:9080/external/usb/1/copy/to/here.jpg'; 787 * }, 788 * failureCb, options_remote_to_usb); 789 * 790 * 791 * // Copy file from redirected server. 792 * var options_redirect = { 793 * source : 'http://remote.site.that.will.redirect/copy_me.txt', 794 * destination : 'file://usb:1/copy/to/here.txt', 795 * maxRedirection: 5 796 * }; 797 * 798 * storage.copyFile(successCb, failureCb, options_redirect); 799 * 800 * // Copy file from ftp server. 801 * var options_ftp = { 802 * source : 'ftp://user:password@remote.ftp.site/copy_me.txt', 803 * destination : 'file://internal/copy/to/here.txt', 804 * }; 805 * 806 * storage.copyFile(successCb, failureCb, options_ftp); 807 * 808 * // Copy internal file to ftp server. 809 * var options_ftp2 = { 810 * source : 'file://internal/send/me/away.txt', 811 * destination : 'ftp://user:password@remote.ftp.site/sent.txt', 812 * }; 813 * 814 * storage.copyFile(successCb, failureCb, options_ftp2); 815 * } 816 * 817 * @class storage 818 * @param {Function} 819 * successCallback success callback function. 820 * @param {Function} 821 * errorCallback failure callback function. 822 * @param {Object} options 823 * <div align=left> 824 * <table class="hcap_spec" width=400> 825 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 826 * <tbody> 827 * <tr><th>source</th><th>{@link Storage.SCAP_URI}</th><th>URI to the source file</a></th><th>required</th></tr> 828 * <tr class="odd"><tr><th>destination</th><th>{@link Storage.SCAP_URI}</th><th>URI to the destination file. </a></th><th>required</th></tr> 829 * <th>ftpOption</th><th>Object</th><th>FTP/SFTP options. Additional options for FTP setting.</th><th>optional</th></tr> 830 * <tr class="odd"><tr><th>ftpOption.secureOptions</th><th>Object</th><th>secure FTP options</a></th><th>optional</th></tr> 831 * <th>ftpOption.secureOptions.privateKey</th><th>String</th><th>Private key for either key-based or hostbased user authentication (OpenSSH format)</a></th><th>optional</th></tr> 832 * <tr class="odd"><tr><th>ftpOption.secureOptions.passphrase</th><th>String</th><th>For an encrypted private key, this is the passphrase used to decrypt it</a></th><th>optional</th></tr> 833 * <th>ftpOption.connTimeout</th><th>Number</th><th>How long (in milliseconds) to wait for the control connection to be established (default : 10000 ms)</a></th><th>optional</th></tr> 834 * <tr class="odd"><tr><th>ftpOption.pasvTimeout</th><th>Number</th><th>How long (in milliseconds) to wait for a PASV data connection to be established (default : 10000 ms)</a></th><th>optional</th></tr> 835 * <th>ftpOption.keepalive</th><th>Number</th><th>How often (in milliseconds) to send a 'dummy'(NOOP) command to keep the connection alive (default : 10000 ms)</a></th><th>optional</th></tr> 836 * <tr class="odd"><th>httpOption</th><th>Object</th><th>HTTP/HTTPS file copy options</th><th>optional</th></tr> 837 * <th>httpOption.maxRedirection</th><th>Number</th><th>Maximum number of allowed redirections.</br> 838 * Default value is 0, which means no redirection is allowed.</br>Request will be redirected if the response code was 301, 839 * 302,303, or 307 and a valid location was found in the response header. </br> 840 * This option is ignored if the source file is not a remote file. Maximum number of redirection is 5.</th><th>optional</th></tr> 841 * <tr class="odd"><tr><th>httpOption.headers</th><th>Object</th> 842 * <th>The [name : value] pairs that will be included in the HTTP request header, for remote file request. </br> 843 * This header data will be cascaded during redirection. </br> 844 * Maximum size of header data that can be contained is 1KB. </br> 845 * </a></th><th>optional</th></tr> 846 * <tr><th>httpOption.timeout</th><th>Number</th> 847 * <th> Milliseconds before the underlying TCP connection times out. 0 is for no time out. Default value is 0.</br> 848 * Note that if there is a server side timeout, copy file can timeout before the timeout value set by this option. 849 * </th><th>optional</th></tr> 850 * </tbody> 851 * </table> 852 * </div> 853 * 854 * @returns 855 * <p> 856 * After the method is successfully executed, successCallback is called without any parameter.</br> 857 * If an error occurs, errorCallback is called with errorCode and errorText. </br> 858 * To see how error codes are defined, check {@link Error.ERROR_CODE} 859 * </p> 860 * 861 * @since 1.0 862 * @since 1.1 access to local file from remote application 863 * @since 1.2 options.maxRedirection 864 * @since 1.3 options.ftpOption 865 * @since 1.3 options.maxRedirection moves to options.httpOption.maxRedirection 866 * @since 1.3 options.httpOption.headers 867 * @since 1.3 options.httpOption.timeout 868 */ 869 Storage.prototype.copyFile = function (successCallback, errorCallback, options) { 870 871 log("Options: " + JSON.stringify(options, null, 3)); 872 873 if (options.maxRedirection && options.maxRedirection > 5) { 874 log("Bad options TOO MANY REDIRECTION"); 875 errorCallback({ errorCode: "BAD_PARAMETER", errorText: "Redirect cannot be more that 5" }); 876 return; 877 } 878 if (options.headers && JSON.stringify(options.headers).length > 1024) { 879 log("header too long header too long"); 880 errorCallback({ errorCode: "BAD_PARAMETER", errorText: "Header data cannot be bigger than 1K" }); 881 return; 882 } 883 884 if (typeof options.httpOption === 'undefined') { 885 options.httpOption = {}; 886 } 887 888 if (options.httpOption.headers && JSON.stringify(options.httpOption.headers).length > 1024) { 889 log("header too long header too long"); 890 errorCallback({ 891 errorCode: "BAD_PARAMETER", 892 errorText: "Header data cannot be bigger than 1K" 893 }); 894 return; 895 } 896 897 if (options.maxRedirection || options.headers) { 898 if (options.maxRedirection && typeof options.httpOption.maxRedirection === 'undefined') { 899 options.httpOption.maxRedirection = options.maxRedirection; 900 } 901 if (options.headers && typeof options.httpOption.headers === 'undefined') { 902 options.httpOption.headers = options.headers; 903 } 904 } 905 906 if (typeof options.httpOption.maxRedirection !== 'undefined') { 907 if (typeof options.maxRedirection !== 'undefined') { 908 if (options.httpOption.maxRedirection !== options.maxRedirection) { 909 // What do you want that use maxRedirection? Both values are different. 910 errorCallback({ 911 errorCode: "BAD_PARAMETER", 912 errorText: "Both options.httpOption.maxRedirection and options.maxRedirection are exists," 913 + "but different value. What value you want to use?" 914 }); 915 return; 916 } 917 } 918 else 919 options.maxRedirection = options.httpOption.maxRedirection; 920 } 921 922 log(options); 923 924 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 925 method: "fs/copyFile", 926 parameters: { 927 dest: options.destination, 928 src: options.source, 929 ftpOption: options.ftpOption, 930 httpOption: options.httpOption 931 }, 932 onSuccess: function (result) { 933 if (result.returnValue === true) { 934 log("SUCCESS"); 935 successCallback(); 936 } 937 else { 938 log("Err: " + result.errorText); 939 errorCallback({ 940 errorCode: result.errorCode, 941 errorText: result.errorText 942 }); 943 } 944 }, 945 onFailure: function (result) { 946 log("Err: " + result.errorText); 947 errorCallback({ 948 errorCode: result.errorCode, 949 errorText: result.errorText 950 }); 951 } 952 }); 953 }; 954 955 /** 956 * <p> 957 * Removes file in internal or external storage. 958 * Target path is described in URI form. 959 * </p> 960 * If the target path is a file, it will be removed.</br> 961 * If the target path is a directory, the directory will be removed.</br> 962 * If 'recursive' parameter is 'true', any file or directory in the target directory will be removed.</br> 963 * If 'recursive' parameter is 'false', operation will fail if there is any file in that directory.</br> 964 * <p> 965 * file://internal/external, file://usb:[index]/content are predefined directory for special use, and cannot be removed. 966 * </p> 967 * 968 * @example 969 * 970 * function removeFile() { 971 * var successCb = function (){ 972 * console.log("Removing File done."); 973 * }; 974 * 975 * var failureCb = function(cbObject){ 976 * var errorCode = cbObject.errorCode; 977 * var errorText = cbObject.errorText; 978 * console.log( " Error Code [" + errorCode + "]: " + errorText); 979 * }; 980 * 981 * 982 * //delete a file 983 * var options = { 984 * file: 'file://internal/delete_me.txt', 985 * }; 986 * 987 * var storage = new Storage(); 988 * storage.removeFile(successCb, failureCb, options); 989 * 990 * //delete a directory and contents in it 991 * var options = { 992 * file: 'file://internal/delete/this/directory/', 993 * recursive : true 994 * }; 995 * 996 * storage.removeFile(successCb, failureCb, options); 997 * 998 * //delete a directory, only if it's empty 999 * var options = { 1000 * file: 'file://internal/empty/directory/', 1001 * recursive : false 1002 * }; 1003 * 1004 * storage.removeFile(successCb, failureCb, options); 1005 * } 1006 * 1007 * @class storage 1008 * @param {Function} 1009 * successCallback success callback function. 1010 * @param {Function} 1011 * errorCallback failure callback function. 1012 * @param {Object} options 1013 * <div align=left> 1014 * <table class="hcap_spec" width=400> 1015 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1016 * <tbody> 1017 * <tr><th>file</th><th>{@link Storage.SCAP_URI}</th><th>URI to the file to delete</a></th><th>required</th></tr> 1018 * <tr class="odd"><tr><th>recursive</th><th>Boolean</th><th>only meaningful when removing a directory. Default value is 'false'.</br> 1019 * If true, the directory and all contents in it will be removed.</br> 1020 * If false, removing the directory will fail if it is not empty. 1021 * </a></th><th>optional</th></tr> 1022 * </tbody> 1023 * </table> 1024 * </div> 1025 * 1026 * @returns 1027 * <p> 1028 * After the method is successfully executed, successCallback is called without any parameter.</br> 1029 * If an error occurs, errorCallback is called with errorCode and errorText. 1030 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1031 * </p> 1032 * 1033 * @since 1.0 1.1 options.recursive 1034 */ 1035 Storage.prototype.removeFile = function (successCallback, errorCallback, options) { 1036 1037 if (!(options && isValidFileURI(options.file))) { 1038 errorCallback({ 1039 errorCode: "BAD_PARAMETER", 1040 errorText: "options.file is a mandatory parameter" 1041 }); 1042 return; 1043 } 1044 var param = { 1045 file: options.file 1046 }; 1047 if (options.recursive === true) { 1048 param.recursive = true; 1049 } 1050 1051 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1052 method: "fs/removeFile", 1053 parameters: param, 1054 onSuccess: function (result) { 1055 1056 log("onSuccess"); 1057 1058 if (result.returnValue === true) { 1059 successCallback(); 1060 } 1061 else { 1062 errorCallback({ 1063 errorCode: result.errorCode, 1064 errorText: result.errorText 1065 }); 1066 } 1067 }, 1068 onFailure: function (result) { 1069 log("onFailure"); 1070 errorCallback({ 1071 errorCode: result.errorCode, 1072 errorText: result.errorText 1073 }); 1074 } 1075 }); 1076 }; 1077 1078 /** 1079 * <p> 1080 * Lists files in a directory stored in external or internal memory. 1081 * Directory location is in URI format. 1082 * Listing a directory beyond the application root path is not allowed. 1083 * </p> 1084 * 1085 * @example 1086 * 1087 * function listFiles() { 1088 * 1089 * var successCb = function (cbObject){ 1090 * var files = cbObject.files; 1091 * for(var i = 0 ; i < files.length; ++i){ 1092 * var fileInfo = files[i]; 1093 * console.log("File Name: " + fileInfo.name); 1094 * console.log("File Type: " + fileInfo.type); 1095 * console.log("File Size: " + fileInfo.size); 1096 * } 1097 * }; 1098 * 1099 * var failureCb = function(cbObject){ 1100 * var errorCode = cbObject.errorCode; 1101 * var errorText = cbObject.errorText; 1102 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1103 * }; 1104 * 1105 * // List files in the internal memory 1106 * var listOption = { 1107 * path: "file://internal/list/this/dir" 1108 * }; 1109 * 1110 * var storage = new Storage(); 1111 * storage.listFiles(successCb, failureCb, listOption); 1112 * 1113 * // List files in the mass storage device in USB port 1. 1114 * var listOption = { 1115 * path: "file://usb:1/list/this/dir" 1116 * }; 1117 * 1118 * storage.listFiles(successCb, failureCb, listOption); 1119 * 1120 * } 1121 * 1122 * @class storage 1123 * @param {Function} 1124 * successCallback success callback function. 1125 * @param {Function} 1126 * errorCallback failure callback function. 1127 * 1128 * @param {Object} options 1129 * <div align=left> 1130 * <table class="hcap_spec" width=400> 1131 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1132 * <tbody> 1133 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the directory to look for.</a></th><th>required</th></tr> 1134 * </tbody> 1135 * </table> 1136 * </div> 1137 * 1138 * @returns 1139 * <p> 1140 * After the method is successfully executed, successCallback is called with total count and an array of file info, which contains a list of File Info Object. 1141 * '.' and '..' will not be included in the list. 1142 * <div align=left> 1143 * <table class="hcap_spec" width=400> 1144 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 1145 * <tbody> 1146 * <tr><th>totalCount</th><th>Number</th> 1147 * <th>Number of items</th> 1148 * </tr> 1149 * <tr><th>files</th><th>Array</th> 1150 * <th>List of files in the directory. File Info has following properties.</th> 1151 * </tr> 1152 * 1153 * <tr><th>files.name</th><th>String</th> 1154 * <th>Name of the file</th> 1155 * </tr> 1156 * 1157 * <tr><th>files.type</th><th>String</th> 1158 * <th>Type of the file</th> 1159 * </tr> 1160 * 1161 * <tr><th>files.size</th><th>Number</th> 1162 * <th>Size of the File</th> 1163 * </tr> 1164 * 1165 * </tbody> 1166 * </table> 1167 * </div> 1168 * </p> 1169 * <p> 1170 * If an error occurs, errorCallback is called with errorCode and errorText. 1171 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1172 * </p> 1173 * 1174 * @since 1.0 1175 * @since 1.1 list a directory 1176 */ 1177 Storage.prototype.listFiles = function (successCallback, errorCallback, options) { 1178 var param = {}; 1179 1180 if (options && options.path) { 1181 if (isValidFileURI(options.path)) { 1182 param.pathURI = options.path; 1183 } 1184 else { 1185 errorCallback({ 1186 errorCode: "BAD_PARAMETER", 1187 errorText: "File URI is not valid." 1188 }); 1189 return; 1190 } 1191 } 1192 else { 1193 param.pathURI = "file://internal/"; 1194 } 1195 1196 service.Request("luna://com.webos.service.commercial.signage.storageservice/", { 1197 method: "fs/listFiles", 1198 parameters: param, 1199 onSuccess: function (result) { 1200 if (result.returnValue === true) { 1201 var files = []; 1202 for (var i = 0; i < result.files.length; ++i) { 1203 log(result.files[i]); 1204 var fileinfo = { 1205 name: result.files[i].name, 1206 type: (result.files[i].type === 'folder') ? 'folder' : 'file', 1207 size: result.files[i].size 1208 }; 1209 files.push(fileinfo); 1210 } 1211 1212 var cbObj = { 1213 files: files, 1214 totalCount: result.totalCount 1215 }; 1216 successCallback(cbObj); 1217 } 1218 else { 1219 errorCallback({ 1220 errorCode: result.errorCode, 1221 errorText: result.errorText 1222 }); 1223 } 1224 }, 1225 onFailure: function (result) { 1226 errorCallback({ 1227 errorCode: result.errorCode, 1228 errorText: result.errorText 1229 }); 1230 } 1231 }); 1232 }; 1233 1234 /** 1235 * <p> 1236 * Gets internal memory status. 1237 * Returns free space and total space, in kilobytes. 1238 * If any external storage device is connected, the storage info for that device will be returned as well. 1239 * </p> 1240 * 1241 * @example 1242 * 1243 * function getStorageInfo() { 1244 * var successCb = function (cbObject){ 1245 * var free = cbObject.free; 1246 * var total = cbObject.total; 1247 * var used = cbObject.used; 1248 * var externals = cbObject.externalMemory; 1249 * 1250 * console.log( "Total: " + total + "kilobytes"); 1251 * console.log( "Free: " + free + "kilobytes"); 1252 * console.log( "Used: " + used + "kilobytes"); 1253 * 1254 * for(var uri in externals){ 1255 * var external = externals[uri]; 1256 * console.log("base uri: " + uri); // ex) usb:1 1257 * console.log("Free: " + external.free); 1258 * console.log("Used: " + external.used); 1259 * console.log("Total: " + external.total); 1260 * } 1261 * }; 1262 * 1263 * var failureCb = function(cbObject){ 1264 * var errorCode = cbObject.errorCode; 1265 * var errorText = cbObject.errorText; 1266 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1267 * }; 1268 * 1269 * var storage = new Storage(); 1270 * storage.getStorageInfo(successCb, failureCb); 1271 * 1272 * } 1273 * 1274 * @class storage 1275 * @param {Function} 1276 * successCallback success callback function. 1277 * @param {Function} 1278 * errorCallback failure callback function. 1279 * @returns 1280 * <p> 1281 * After the method is successfully executed, successCallback is called with free and total space. 1282 * <div align=left> 1283 * <table class="hcap_spec" width=400> 1284 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 1285 * <tbody> 1286 * <tr><th>free</th><th>Number</th> 1287 * <th> 1288 * Free space in internal memory, in KB. 1289 * </th> 1290 * </tr> 1291 * <tr><th>total</th><th>Number</th> 1292 * <th> 1293 * Total space in internal memory, in KB. 1294 * </th> 1295 * </tr> 1296 * <tr><th>used</th><th>Number</th> 1297 * <th> 1298 * Used space in internal memory, in KB. 1299 * </th> 1300 * </tr> 1301 * <tr><th>externalMemory</th><th>Array</th> 1302 * <th> 1303 * <p> 1304 * List of external memory connected to the device (ex.usb:1). Optional. 1305 * </p> 1306 * <p>Each external memory item is a JSON object containing following fields. </p> 1307 * <table align="center" class="hcap_spec" width=400> 1308 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 1309 * <tbody> 1310 * <tr><th>free</th><th>Number</th><th>Free space in the external memory, in KB.</th></tr> 1311 * <tr><th>used</th><th>Number</th><th>Used space in the external memory, in KB.</th></tr> 1312 * <tr><th>total</th><th>Number</th><th>Total space in the external memory, in KB.</th></tr> 1313 * </tbody> 1314 * </table> 1315 * </th> 1316 * </tr> 1317 * </tbody> 1318 * </table> 1319 * </div> 1320 * </p> 1321 * <p> 1322 * If an error occurs, errorCallback is called with errorCode and errorText. 1323 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1324 * </p> 1325 * 1326 * @since 1.0 1327 * @since 1.1 USB storage information 1328 * @since 1.3 SDCard storage information 1329 */ 1330 Storage.prototype.getStorageInfo = function (successCallback, errorCallback) { 1331 1332 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1333 method: "fs/storageInfo", 1334 parameters: {}, 1335 onSuccess: function (result) { 1336 log("returned : " + JSON.stringify(result, null, 3)); 1337 if (result.returnValue === true) { 1338 log("returned : " + JSON.stringify(result, null, 3)); 1339 var cbObj = { 1340 free: result.spaceInfo.freeSize, 1341 total: result.spaceInfo.totalSize, 1342 used: result.spaceInfo.usedSize, 1343 externalMemory: result.externalStorage 1344 }; 1345 successCallback(cbObj); 1346 } 1347 else { 1348 errorCallback({ 1349 errorCode: result.errorCode, 1350 errorText: result.errorText 1351 }); 1352 } 1353 }, 1354 onFailure: function (result) { 1355 errorCallback({ 1356 errorCode: result.errorCode, 1357 errorText: result.errorText 1358 }); 1359 } 1360 }); 1361 }; 1362 1363 /** 1364 * <p> 1365 * Creates a directory. 1366 * The path should be described in URI format. 1367 * If the URI is for external memory, external storage device should be connected to the external memory port with proper permission. 1368 * The directory will be created recursively. 1369 * </p> 1370 * 1371 * @example 1372 * 1373 * function mkdir() { 1374 * var successCb = function (){ 1375 * console.log( "directory created successfully"); 1376 * }; 1377 * 1378 * var failureCb = function(cbObject){ 1379 * var errorCode = cbObject.errorCode; 1380 * var errorText = cbObject.errorText; 1381 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1382 * }; 1383 * 1384 * // The directory will be created recursively. 1385 * var mkdirOption = { 1386 * path: "file://internal/create/this/directory" 1387 * }; 1388 * 1389 * var storage = new Storage(); 1390 * storage.mkdir(successCb, failureCb, mkdirOption); 1391 * 1392 * } 1393 * 1394 * @class storage 1395 * @param {Function} 1396 * successCallback success callback function. 1397 * @param {Function} 1398 * errorCallback failure callback function. 1399 * 1400 * @param {Object} options 1401 * <div align=left> 1402 * <table class="hcap_spec" width=400> 1403 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1404 * <tbody> 1405 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the directory to create. </a></th><th>required</th></tr> 1406 * </tbody> 1407 * </table> 1408 * </div> 1409 * 1410 * @returns 1411 * <p> 1412 * After the method is successfully executed, successCallback is called without any parameter.</br> 1413 * If an error occurs, errorCallback is called with errorCode and errorText. 1414 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1415 * </p> 1416 * 1417 * @since 1.1 1418 */ 1419 Storage.prototype.mkdir = function (successCallback, errorCallback, options) { 1420 if (!(options && isValidFileURI(options.path))) { 1421 errorCallback({ 1422 errorCode: "BAD_PARAMETER", 1423 errorText: "options.path is a mandatory parameter" 1424 }); 1425 return; 1426 } 1427 var param = { 1428 pathURI: options.path 1429 }; 1430 1431 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1432 method: "fs/mkdir", 1433 parameters: param, 1434 onSuccess: function (result) { 1435 1436 log("onSuccess"); 1437 1438 if (result.returnValue === true) { 1439 successCallback(); 1440 } 1441 else { 1442 errorCallback({ 1443 errorCode: result.errorCode, 1444 errorText: result.errorText 1445 }); 1446 } 1447 }, 1448 onFailure: function (result) { 1449 log("onFailure"); 1450 errorCallback({ 1451 errorCode: result.errorCode, 1452 errorText: result.errorText 1453 }); 1454 } 1455 }); 1456 }; 1457 1458 /** 1459 * <p> 1460 * Checks if the given file exists or not. 1461 * The path should be in URI format. 1462 * If the URI is for external memory, external storage device must be connected to the external memory port with proper permission. 1463 * </p> 1464 * 1465 * @example 1466 * 1467 * function exists() { 1468 * var successCb = function (cbObject){ 1469 * var exists = cbObject.exists; 1470 * console.log( "The file exists: " + exists); 1471 * }; 1472 * 1473 * var failureCb = function(cbObject){ 1474 * var errorCode = cbObject.errorCode; 1475 * var errorText = cbObject.errorText; 1476 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1477 * }; 1478 * 1479 * var existsOption = { 1480 * path: "file://internal/to/be/or/not/to/be" 1481 * }; 1482 * 1483 * var storage = new Storage(); 1484 * storage.exists(successCb, failureCb, existsOption); 1485 * 1486 * } 1487 * 1488 * @class storage 1489 * @param {Function} 1490 * successCallback success callback function. 1491 * @param {Function} 1492 * errorCallback failure callback function. 1493 * 1494 * @param {Object} options 1495 * <div align=left> 1496 * <table class="hcap_spec" width=400> 1497 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1498 * <tbody> 1499 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the resource (internal/usb/sdcard).</a></th><th>required</th></tr> 1500 * </tbody> 1501 * </table> 1502 * </div> 1503 * 1504 * @returns 1505 * <p> 1506 * After the method is successfully executed, successCallback is called with a boolean attribute 'exists', which is true if the file exists and false otherwise.</br> 1507 * If an error occurs, errorCallback is called with errorCode and errorText. 1508 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1509 * </p> 1510 * 1511 * @since 1.1 1512 */ 1513 Storage.prototype.exists = function (successCallback, errorCallback, options) { 1514 1515 if (!(options && isValidFileURI(options.path))) { 1516 log("BAD_PARAMETER"); 1517 1518 errorCallback({ 1519 errorCode: "BAD_PARAMETER", 1520 errorText: "options.path is a mandatory parameter" 1521 }); 1522 return; 1523 } 1524 var param = { 1525 pathURI: options.path 1526 }; 1527 1528 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1529 method: "fs/exists", 1530 parameters: param, 1531 onSuccess: function (result) { 1532 1533 log("onSuccess"); 1534 1535 if (result.returnValue === true) { 1536 log("returned : " + JSON.stringify(result, null, 3)); 1537 var cbObj = { 1538 exists: result.exists 1539 }; 1540 successCallback(cbObj); 1541 } 1542 else { 1543 errorCallback({ 1544 errorCode: result.errorCode, 1545 errorText: result.errorText 1546 }); 1547 } 1548 }, 1549 onFailure: function (result) { 1550 log("onFailure"); 1551 errorCallback({ 1552 errorCode: result.errorCode, 1553 errorText: result.errorText 1554 }); 1555 } 1556 }); 1557 }; 1558 1559 /** 1560 * <p> 1561 * Reads from a file.<br> 1562 * It is designed to read a small data file from filesystem (not suited for a big data file). 1563 * </p> 1564 * <p> 1565 * Note : For reading a big chunk of data, it is recommended to use AJAX with local file. 1566 * </p> 1567 * @example 1568 * 1569 * function readFile() { 1570 * // This example will read a file as binary. 1571 * 1572 * var successCb = function (cbObject){ 1573 * // If file is read as binary, array of uint8 will be returned. 1574 * // Create an image element, and set the source as the binary data. 1575 * 1576 * var binary_data = cbObject.data; 1577 * var data_base64 = bin_array_to_base64(binary_data); 1578 * var ele = document.createElement('img'); 1579 * ele.src = "data:image/jpeg;base64, " + data_base64; 1580 * document.body.appendChild(ele); 1581 * }; 1582 * 1583 * var failureCb = function(cbObject){ 1584 * var errorCode = cbObject.errorCode; 1585 * var errorText = cbObject.errorText; 1586 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1587 * }; 1588 * 1589 * // Read file from the start, read the whole file, and read as binary 1590 * var options = { 1591 * path: "file://internal/image.jpg", 1592 * position : 0, 1593 * encoding: 'binary' 1594 * }; 1595 * 1596 * var storage = new Storage(); 1597 * storage.readFile(successCb, failureCb, options); 1598 * 1599 * 1600 * // This example will read file as text. 1601 * var successCb = function (cbObject){ 1602 * // If file is read as text, utf encoded string will be returned. 1603 * // Create an image element, and set the source as the binary data. 1604 * 1605 * var data_text = cbObject.data; 1606 * var ele = document.createElement('div'); 1607 * ele.innerHTML = "Text is read: " + data_text; 1608 * document.body.appendChild(ele); 1609 * }; 1610 * 1611 * var failureCb = function(cbObject){ 1612 * var errorCode = cbObject.errorCode; 1613 * var errorText = cbObject.errorText; 1614 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1615 * }; 1616 * 1617 * // Read file from the start, read the whole file, and read as text. 1618 * var options = { 1619 * path : "file://internal/text.txt", 1620 * position : 0, 1621 * encoding: 'utf8' 1622 * }; 1623 * 1624 * var storage = new Storage(); 1625 * storage.readFile(successCb, failureCb, options); 1626 * 1627 * } 1628 * 1629 * @example 1630 * // This is a recommended way of reading a big chunk of data from file with JQuery Ajax. 1631 * // Reading a data chunk bigger than 50MB is not recommended because it can lead to memory overflow (depends on system). 1632 * function readFileAjax(){ 1633 * $.ajax({ 1634 * url: "http://127.0.0.1:9080/chunk.data" 1635 * }) 1636 * .fail(function(err){ 1637 * // Handle error. 1638 * }) 1639 * .done(function(data){ 1640 * // Handle the data. 1641 * }); 1642 * } 1643 * 1644 * @class storage 1645 * @param {Function} 1646 * successCallback success callback function. 1647 * @param {Function} 1648 * errorCallback failure callback function. 1649 * 1650 * @param {Object} options 1651 * <div align=left> 1652 * <table class="hcap_spec" width=400> 1653 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1654 * <tbody> 1655 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the resource (internal/usb/sdcard). </a></th><th>required</th></tr> 1656 * <tr class="odd"><tr><th>position</th><th>Number</th><th>Position where this file will be read from. Default value is 0.</br> 1657 * If the value of the position parameter is out of the range of the input file, error will be returned.</a></th><th>optional</th></tr> 1658 * <tr><th>length</th><th>Number</th><th>The length of the Read buffer. Maximum length of the buffer that can be read is currently 10KB. </br> 1659 * Default value is 10KB. </br>If the size of the file intended to be read is smaller than the length parameter, 1660 * return data will include the contents of the file.</a></th><th>optional</th></tr> 1661 * <tr class="odd"><tr><th>encoding</th><th>String</th><th>Encoding method to be used for return value. </br> 1662 * Default value is 'utf8'. Value of encoding can be:</br> 1663 * 'utf8' : Encoded as UTF-8. Return value will be a string.</br> 1664 * 'base64' : Encoded as base64. Return value will be a string.</br> 1665 * 'binary' : Raw binary data. Return value will be an ArrayBuffer.</br></a></th><th>optional</th></tr> 1666 * </tbody> 1667 * </table> 1668 * </div> 1669 * @returns 1670 * <p> 1671 * A string containing the file data with given encoding will be returned ('utf8', 'base64').</br> 1672 * If the encoding is 'binary', an ArrayBuffer will be returned.</br> 1673 * </p> 1674 * <p> 1675 * After the method is successfully executed, successCallback is called with file data.</br> 1676 * If an error occurs, errorCallback is called with errorCode and errorText. 1677 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1678 * </p> 1679 * 1680 * @since 1.2 1681 */ 1682 Storage.prototype.readFile = function (successCallback, errorCallback, options) { 1683 if (!options) { 1684 errorCallback({ 1685 errorCode: "BAD_PARAMETER", 1686 errorText: "options.path is a mandatory parameter" 1687 }); 1688 } 1689 else if (!isValidFileURI(options.path)) { 1690 errorCallback({ 1691 errorCode: "BAD_PARAMETER", 1692 errorText: "options.path is a mandatory parameter" 1693 }); 1694 } 1695 else if (options.length && (options.length > Storage.MAX_BUFFER_LENGTH || options.length < 1)) { 1696 errorCallback({ 1697 errorCode: "BAD_PARAMETER", 1698 errorText: "length should be > 0 and < " + Storage.MAX_BUFFER_LENGTH 1699 }); 1700 } 1701 else if (options.position && (options.position < 0)) { 1702 errorCallback({ 1703 errorCode: "BAD_PARAMETER", 1704 errorText: "position should be > 0" 1705 }); 1706 } 1707 else { 1708 var params = {}; 1709 1710 params.path = options.path; 1711 params.length = options.length ? options.length : Storage.MAX_BUFFER_LENGTH; 1712 params.position = options.position ? options.position : 0; 1713 params.encoding = options.encoding ? options.encoding : 'utf-8'; 1714 1715 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1716 method: "fs/readFile", 1717 parameters: params, 1718 onSuccess: function (result) { 1719 if (result.returnValue) { 1720 if (params.encoding === 'binary') { 1721 // Read as binary so return as ArrayBuffer. 1722 // Returned data is a array of byte. 1723 var byteArray = result.data; 1724 var arrayView = new Uint8Array(byteArray.length); 1725 for (var i = 0; i < byteArray.length; ++i) { 1726 arrayView[i] = byteArray[i]; 1727 } 1728 successCallback({ 1729 data: arrayView.buffer 1730 }); 1731 } 1732 else { 1733 // return as a string 1734 successCallback({ 1735 data: result.data 1736 }); 1737 } 1738 } 1739 else { 1740 errorCallback({ 1741 errorCode: result.errorCode, 1742 errorText: result.errorText 1743 }); 1744 } 1745 }, 1746 onFailure: function (result) { 1747 errorCallback({ 1748 errorCode: result.errorCode, 1749 errorText: result.errorText 1750 }); 1751 } 1752 }); 1753 } 1754 }; 1755 1756 /** 1757 * 1758 * Writes file 1759 * 1760 * @example 1761 * 1762 * function writeFile() { 1763 * // This example will write binary data to file. 1764 * 1765 * var successCb = function (cbObject){ 1766 * console.log( "Successfully writen " + cbObject.written + " bytes" ); 1767 * }; 1768 * 1769 * var failureCb = function(cbObject){ 1770 * var errorCode = cbObject.errorCode; 1771 * var errorText = cbObject.errorText; 1772 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1773 * }; 1774 * 1775 * 1776 * //Read a file as binary with an ajax call. 1777 * var oReq = new XMLHttpRequest(); 1778 * oReq.open("GET", '/my_file.data', true); 1779 * oReq.responseType = "arraybuffer"; 1780 * oReq.onload = function (oEvent) { 1781 * var arrayBuffer = oReq.response; // Note: not oReq.responseText 1782 * 1783 * if (arrayBuffer) { 1784 * var uint8View = new Int8Array(arrayBuffer); 1785 * var array = []; 1786 * for(var i=0;i < uint8View.length;++i) { 1787 * array[i] = uint8View[i]; 1788 * } 1789 * 1790 * // write data from the start, read the whole data, and write as binary 1791 * var options = { 1792 * data: array, 1793 * path: 'file://internal/data.dat', 1794 * position : 0, 1795 * mode :'truncate', 1796 * offset:0, 1797 * length : array.length, 1798 * encoding: 'binary' 1799 * }; 1800 * 1801 * var storage = new Storage(); 1802 * storage.writeFile(successCb, failureCb, options); 1803 * } 1804 * }; 1805 * 1806 * oReq.send(null); 1807 * // This example will write text data to a file. 1808 * 1809 * var successCb = function (cbObject){ 1810 * console.log( "Successfully writen " + cbObject.written + " bytes" ); 1811 * }; 1812 * 1813 * var failureCb = function(cbObject) { 1814 * var errorCode = cbObject.errorCode; 1815 * var errorText = cbObject.errorText; 1816 * console.log( " Error Code [" + errorCode + "]: " + errorText); 1817 * }; 1818 * 1819 * // write Text data, use utf-8 encoding, write all text. 1820 * var textData = "Hello SCAP!!!!!"; 1821 * var options = { 1822 * data: textData, 1823 * path: 'file://internal/text.txt', 1824 * position : 0, 1825 * mode :'truncate', 1826 * offset:0, 1827 * length : textData.length, 1828 * encoding: 'utf8' 1829 * }; 1830 * 1831 * var storage = new Storage(); 1832 * storage.writeFile(successCb, failureCb, options); 1833 * 1834 * } 1835 * 1836 * @class storage 1837 * @param {Function} 1838 * successCallback success callback function. 1839 * @param {Function} 1840 * errorCallback failure callback function. 1841 * 1842 * @param {Object} options 1843 * <div align=left> 1844 * <table class="hcap_spec" width=400> 1845 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 1846 * <tbody> 1847 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the resource (internal/usb/sdcard).</a></th><th>required</th></tr> 1848 * <tr class="odd"><tr><th>data</th><th>ArrayBuffer|String</th><th>Data to write to the file. Data type should be ArrayBuffer if encoding is 'binary' or string otherwise.</a></th><th>required</th></tr> 1849 * <tr><th>mode</th><th>String</th><th>Write mode. Default is 'truncate'.</br> 1850 * 'truncate' : Truncate the file and start writing on it. File will be created if it doesn't exist. </br> 1851 * 'append' : Append to the file. File will be created if it doesn't exist. </br> 1852 * 'position' : Write from the position given by option.position. File must exist for this mode. </br> </a></th><th>optional</th></tr> 1853 * <tr class="odd"><tr><th>position</th><th>Number</th><th>Position where this file will be written. Default value is 0. This option is valid only if mode is 'position'.</br> 1854 * If position is bigger than the existing file for positional write, the gap between the file contents and write position will be filled with '\00' character.</a></th><th>optional</th></tr> 1855 * <tr><th>length</th><th>Number</th><th>Write buffer length in bytes. Maximum buffer size is 10KB. </br>Default value is data.length, 1856 * or 10KB if data.length-offset > 10KB.</a></th><th>optional</th></tr> 1857 * <tr class="odd"><tr><th>encoding</th><th>String</th><th>Encoding to be applied to input data. Default value is 'utf8'.</br> 1858 * 'utf8' : input data is encoded as UTF-8. options.data should be a string.</br> 1859 * 'base64' : input data is encoded as base64. options.data should be a string.</br> 1860 * 'binary' : input data is encoded as raw binary. options.data should be an ArrayBuffer.</br></a></th><th>optional</th></tr> 1861 * <tr><th>offset</th><th>Number</th><th>Offset from buffer. Default value is 0. If offset+length > data.length, error will be returned.</a></th><th>optional</th></tr> 1862 * </tbody> 1863 * </table> 1864 * </div> 1865 * 1866 * @returns 1867 * <p> 1868 * After the method is successfully executed, successCallback is called with the number of bytes written.</br> 1869 * The number of bytes written may be more than the length of the actual data. </br> 1870 * If an error occurs, errorCallback is called with errorCode and errorText. 1871 * To see how error codes are defined, check {@link Error.ERROR_CODE} 1872 * </p> 1873 * 1874 * @since 1.2 1875 */ 1876 Storage.prototype.writeFile = function (successCallback, errorCallback, options) { 1877 if (!options) { 1878 errorCallback({ 1879 errorCode: "BAD_PARAMETER", 1880 errorText: "options.path is a mandatory parameter" 1881 }); 1882 } 1883 else if (!isValidFileURI(options.path)) { 1884 errorCallback({ 1885 errorCode: "BAD_PARAMETER", 1886 errorText: "options.path is a is not valid" 1887 }); 1888 } 1889 else if (!options.data) { 1890 errorCallback({ 1891 errorCode: "BAD_PARAMETER", 1892 errorText: "options.data is a mandatory parameter" 1893 }); 1894 } 1895 else if (options.mode && (options.mode !== 'truncate' && options.mode !== 'append' && options.mode !== 'position')) { 1896 errorCallback({ 1897 errorCode: "BAD_PARAMETER", 1898 errorText: "mode should be 'truncate'|'append'|'position'" 1899 }); 1900 } 1901 else if (options.position && (options.position < 0)) { 1902 errorCallback({ 1903 errorCode: "BAD_PARAMETER", 1904 errorText: "position should be > 0" 1905 }); 1906 } 1907 else if (options.offset && (options.offset < 0)) { 1908 errorCallback({ 1909 errorCode: "BAD_PARAMETER", 1910 errorText: "offset should be > 0" 1911 }); 1912 } 1913 else if (options.length && (options.length > Storage.MAX_BUFFER_LENGTH || options.length < 1)) { 1914 errorCallback({ 1915 errorCode: "BAD_PARAMETER", 1916 errorText: "length should be > 0 and < " + Storage.MAX_BUFFER_LENGTH 1917 }); 1918 } 1919 else if (options.encoding && (options.encoding !== 'utf8' && options.encoding !== 'binary' && options.encoding !== 'base64')) { 1920 errorCallback({ 1921 errorCode: "BAD_PARAMETER", 1922 errorText: "Invalid encoding: " + options.encoding 1923 }); 1924 } 1925 1926 else { 1927 log("REQUEST"); 1928 var params = {}; 1929 params.path = options.path; 1930 params.mode = options.mode ? options.mode : 'truncate'; 1931 params.position = options.position ? options.position : 0; 1932 params.encoding = options.encoding ? options.encoding : 'utf8'; 1933 var offset = options.offset ? options.offset : 0; 1934 // Input data is array Buffer when encoding is binary 1935 if (params.encoding === 'binary') { 1936 log("binary, size is: " + options.data.byteLength); 1937 var uint8View = new Uint8Array(options.data); 1938 log("uint8View: " + uint8View); 1939 var maxLength = options.length ? options.length : Storage.MAX_BUFFER_LENGTH; 1940 var array = []; 1941 var count = 0; 1942 for (var i = offset; i < uint8View.length && count < maxLength; ++i, count++) { 1943 array[count] = uint8View[i]; 1944 } 1945 log("array length: " + count); 1946 1947 params.data = array; 1948 params.length = count; 1949 params.offset = 0; 1950 } 1951 // input data is base64 encoded string if encoding is base64 1952 else if (params.encoding === 'base64') { 1953 var maxLength2 = options.length ? options.length : Storage.MAX_BUFFER_LENGTH; 1954 log("base64, size is: " + options.data.length); 1955 var base64Str = options.data; 1956 var decodedRaw = window.atob(base64Str); 1957 var decoded = decodedRaw.substring(offset, offset + maxLength2); 1958 var arrayView = new Uint8Array(decoded.length); 1959 1960 var j; 1961 for (j = 0; j < decoded.length; j++) { 1962 arrayView[j] = decoded.charCodeAt(j); 1963 } 1964 1965 var array2 = []; 1966 for (j = 0; j < arrayView.length; ++j) { 1967 array2[j] = arrayView[j]; 1968 } 1969 1970 params.data = array2; 1971 params.length = array2.length; 1972 params.offset = 0; 1973 } 1974 // input data is utf-8 text. 1975 else { 1976 var maxLength3 = options.length ? options.length : Storage.MAX_BUFFER_LENGTH; 1977 //var endPosition = (options.offset + maxLength3) > options.data.length ? options.data.length : (options.offset + maxLength3); 1978 params.data = options.data.substring(offset, offset + maxLength3); 1979 params.length = params.data.length; 1980 params.offset = 0; 1981 } 1982 try { 1983 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 1984 method: "fs/writeFile", 1985 parameters: params, 1986 onSuccess: function (result) { 1987 log("onSuccess"); 1988 if (result.returnValue) { 1989 successCallback({ 1990 written: result.written 1991 }); 1992 } 1993 else { 1994 log("FAILED: " + result.errorText); 1995 errorCallback({ 1996 errorCode: result.errorCode, 1997 errorText: result.errorText 1998 }); 1999 } 2000 }, 2001 onFailure: function (result) { 2002 log("onFailure"); 2003 log("FAILED: " + result.errorText); 2004 errorCallback({ 2005 errorCode: result.errorCode, 2006 errorText: result.errorText 2007 }); 2008 } 2009 }); 2010 } catch (err) { 2011 log("EXCEPTION" + err); 2012 errorCallback({ 2013 errorCode: 'STWF', 2014 errorText: 'Storage.writeFile() error is occured during operation.' 2015 }); 2016 } 2017 } 2018 }; 2019 2020 /** 2021 * 2022 * Gets file stat. Stat for linked file is not shown. 2023 * 2024 * @example 2025 * 2026 * function statFile() { 2027 * var successCb = function (cbObject){ 2028 * console.log( "Show File Stat: " ); 2029 * console.log( JSON.stringify(cbObject)); 2030 * }; 2031 * 2032 * var failureCb = function(cbObject){ 2033 * var errorCode = cbObject.errorCode; 2034 * var errorText = cbObject.errorText; 2035 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2036 * }; 2037 * 2038 * var options = { 2039 * path: 'file://internal/myFile.txt', 2040 * }; 2041 * 2042 * var storage = new Storage(); 2043 * storage.statFile(successCb, failureCb, options); 2044 * } 2045 * 2046 * @class storage 2047 * @param {Function} 2048 * successCallback success callback function. 2049 * @param {Function} 2050 * errorCallback failure callback function. 2051 * 2052 * @param {Object} options 2053 * <div align=left> 2054 * <table class="hcap_spec" width=400> 2055 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2056 * <tbody> 2057 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the resource (internal/usb/sdcard).</a></th><th>required</th></tr> 2058 * </tbody> 2059 * </table> 2060 * </div> 2061 * @returns 2062 * <p> 2063 * After the method is successfully executed, successCallback is called with the file stat.</br> 2064 * Example: 2065 * { 2066 * type: file|directory|unknown, 2067 * size: 527, 2068 * atime: Mon, 10 Oct 2011 23:24:11 GMT, 2069 * mtime: Mon, 10 Oct 2011 23:24:11 GMT, 2070 * ctime: Mon, 10 Oct 2011 23:24:11 GMT 2071 * } 2072 * </br> 2073 * If an error occurs, errorCallback is called with errorCode and errorText. 2074 * To see how error codes are defined, check {@link Error.ERROR_CODE} 2075 * </p> 2076 * 2077 * @since 1.2 2078 */ 2079 Storage.prototype.statFile = function (successCallback, errorCallback, options) { 2080 if (!(options && isValidFileURI(options.path))) { 2081 errorCallback({ 2082 errorCode: "BAD_PARAMETER", 2083 errorText: "options.path is a mandatory parameter" 2084 }); 2085 } 2086 else if (!options.path) { 2087 errorCallback({ 2088 errorCode: "BAD_PARAMETER", 2089 errorText: "options.path is a mandatory parameter" 2090 }); 2091 } else { 2092 try { 2093 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 2094 method: "fs/statFile", 2095 parameters: { 2096 path: options.path 2097 }, 2098 onSuccess: function (result) { 2099 log("onSuccess"); 2100 2101 if (result.returnValue) { 2102 successCallback(result.stat); 2103 } 2104 else { 2105 log("FAILED: " + result.errorText); 2106 errorCallback({ 2107 errorCode: result.errorCode, 2108 errorText: result.errorText 2109 }); 2110 } 2111 }, 2112 onFailure: function (result) { 2113 log("onFailure"); 2114 log("FAILED: " + result.errorText); 2115 errorCallback({ 2116 errorCode: result.errorCode, 2117 errorText: result.errorText 2118 }); 2119 } 2120 }); 2121 } catch (err) { 2122 log("EXCEPTION" + err); 2123 errorCallback({ 2124 errorCode: 'STSF', 2125 errorText: 'Storage.statFile() error is occured during operation.' 2126 }); 2127 } 2128 } 2129 }; 2130 2131 /** 2132 * 2133 * Removes all files in given file system. 2134 * 2135 * @example 2136 * 2137 * function removeAll() { 2138 * var successCb = function (cbObject){ 2139 * console.log( "Removed all files " ); 2140 * }; 2141 * 2142 * var failureCb = function(cbObject){ 2143 * var errorCode = cbObject.errorCode; 2144 * var errorText = cbObject.errorText; 2145 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2146 * }; 2147 * 2148 * var options = { 2149 * device: 'internal' // This will remove all files in the internal memory space. 2150 * }; 2151 * 2152 * var storage = new Storage(); 2153 * storage.removeAll(successCb, failureCb, options); 2154 * } 2155 * 2156 * @class storage 2157 * @param {Function} 2158 * successCallback success callback function. 2159 * @param {Function} 2160 * errorCallback failure callback function. 2161 * 2162 * @param {Object} options 2163 * <div align=left> 2164 * <table class="hcap_spec" width=400> 2165 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2166 * <tbody> 2167 * <tr><th>device</th><th>String</th><th>device to remove all files from. (internal, usb:[index], sdcard:[index])</a></th><th>required</th></tr> 2168 * </tbody> 2169 * </table> 2170 * </div> 2171 * @returns 2172 * <p> 2173 * After the method is successfully executed, successCallback is called without any parameter.</br> 2174 * If an error occurs, errorCallback is called with errorCode and errorText. 2175 * To see how error codes are defined, check {@link Error.ERROR_CODE} 2176 * </p> 2177 * 2178 * @since 1.2 2179 */ 2180 Storage.prototype.removeAll = function (successCallback, errorCallback, options) { 2181 if (!options) { 2182 errorCallback({ 2183 errorCode: "BAD_PARAMETER", 2184 errorText: "options.device is a mandatory parameter" 2185 }); 2186 } 2187 else if (!options.device) { 2188 errorCallback({ 2189 errorCode: "BAD_PARAMETER", 2190 errorText: "options.device is a mandatory parameter" 2191 }); 2192 } else { 2193 try { 2194 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 2195 method: "fs/removeAll", 2196 parameters: { 2197 device: options.device 2198 }, 2199 onSuccess: function (result) { 2200 log("onSuccess"); 2201 2202 if (result.returnValue) { 2203 successCallback(); 2204 } 2205 else { 2206 log("FAILED: " + result.errorText); 2207 errorCallback({ 2208 errorCode: result.errorCode, 2209 errorText: result.errorText 2210 }); 2211 } 2212 }, 2213 onFailure: function (result) { 2214 log("onFailure"); 2215 log("FAILED: " + result.errorText); 2216 errorCallback({ 2217 errorCode: result.errorCode, 2218 errorText: result.errorText 2219 }); 2220 } 2221 }); 2222 } catch (err) { 2223 log("EXCEPTION" + err); 2224 errorCallback({ 2225 errorCode: 'STRA', 2226 errorText: 'Storage.removeAll() error is occured during operation.' 2227 }); 2228 } 2229 } 2230 }; 2231 2232 /** 2233 * 2234 * Flushes modified files to filesystem. 2235 * 2236 * @example 2237 * 2238 * function fsync() { 2239 * // This example will copy a file to USB and sync it. 2240 * 2241 * var failureCb = function(cbObject){ 2242 * var errorCode = cbObject.errorCode; 2243 * var errorText = cbObject.errorText; 2244 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2245 * }; 2246 * 2247 * var storage = new Storage(); 2248 * storage.copyFile( 2249 * function(){ // Copy was success. fsync the file. 2250 * storage.fsync( 2251 * function(){ 2252 * console.log("File synched!!!!!!!!!!"); 2253 * }, 2254 * failureCb, 2255 * {path : "file://usb:1/file.jpg"} 2256 * ); 2257 * }, 2258 * failureCb, 2259 * {source:"file://internal/this.jpg", destination:"file://usb:1/file.jpg"} 2260 * ); 2261 * 2262 * // This example will sync whole file system. 2263 * var failureCb = function(cbObject){ 2264 * var errorCode = cbObject.errorCode; 2265 * var errorText = cbObject.errorText; 2266 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2267 * }; 2268 * 2269 * storage.copyFile( 2270 * function(){ // Copy was success. fsync the device. 2271 * storage.fsync( 2272 * function(){ 2273 * console.log("File synched!!!!!!!!!!"); 2274 * }, 2275 * failureCb, // Failure Callback 2276 * {} // Options 2277 * ); 2278 * }, 2279 * failureCb, // Failure Callback 2280 * {source:"file://internal/this.jpg", destination:"file://usb:1/file.jpg"} // Options 2281 * ); 2282 * 2283 * } 2284 * 2285 * @class storage 2286 * @param {Function} 2287 * successCallback success callback function. 2288 * @param {Function} 2289 * errorCallback failure callback function. 2290 * 2291 * @param {Object} options 2292 * <div align=left> 2293 * <table class="hcap_spec" width=400> 2294 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2295 * <tbody> 2296 * <tr><th>path</th><th>{@link Storage.SCAP_URI}</th><th>URI to the resource (internal/usb/sdcard).</br>If this parameter is not provided, whole file system is synced using 'sync' linux command.</a></th><th>optional</th></tr> 2297 * </tbody> 2298 * </table> 2299 * </div> 2300 * 2301 * @returns 2302 * <p> 2303 * After the method is successfully executed, successCallback is called without any parameter.</br> 2304 * If an error, errorCallback is called with errorCode and errorText. 2305 * To see how error codes are defined, check {@link Error.ERROR_CODE} 2306 * </p> 2307 * 2308 * @since 1.2 2309 */ 2310 Storage.prototype.fsync = function (successCallback, errorCallback, options) { 2311 try { 2312 var params = {}; 2313 if (options && options.path) { 2314 if (isValidFileURI(options.path)) { 2315 params.path = options.path; 2316 } 2317 else { 2318 errorCallback({ 2319 errorCode: "BAD_PARAMETER", 2320 errorText: "Invalid File URI" 2321 }); 2322 return; 2323 } 2324 } 2325 2326 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 2327 method: "fs/fsyncFile", 2328 parameters: params, 2329 onSuccess: function (result) { 2330 log("onSuccess"); 2331 if (result.returnValue) { 2332 successCallback(); 2333 } 2334 else { 2335 log("FAILED: " + result.errorText); 2336 errorCallback({ 2337 errorCode: result.errorCode, 2338 errorText: result.errorText 2339 }); 2340 } 2341 }, 2342 onFailure: function (result) { 2343 log("onFailure"); 2344 log("FAILED: " + result.errorText); 2345 errorCallback({ 2346 errorCode: result.errorCode, 2347 errorText: result.errorText 2348 }); 2349 } 2350 }); 2351 } catch (err) { 2352 log("EXCEPTION" + err); 2353 errorCallback({ 2354 errorCode: 'STFS', 2355 errorText: 'Storage.fsync() error is occured during operation.' 2356 }); 2357 } 2358 }; 2359 2360 /** 2361 * 2362 * Moves a file or directory. 2363 * If newPath already exists, it will be replaced. </br> 2364 * If newPath and oldPath refer to a same file, it will return success but do nothing. </br> 2365 * If oldPath is a directory, newPath must be either non-existing or emptry directory. </br> 2366 * 2367 * <p> 2368 * file://internal/external, file://usb:[usb_port]/content are predefined directory for special use, and cannot be moved. 2369 * </p> 2370 * @example 2371 * 2372 * function moveFile() { 2373 * var successCb = function (){ 2374 * console.log("Move File done."); 2375 * }; 2376 * 2377 * var failureCb = function(cbObject){ 2378 * var errorCode = cbObject.errorCode; 2379 * var errorText = cbObject.errorText; 2380 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2381 * }; 2382 * 2383 * var options = { 2384 * oldPath: 'file://internal/org.txt', 2385 * newPath : 'file://internal/new.txt' 2386 * }; 2387 * 2388 * var storage = new Storage(); 2389 * storage.moveFile(successCb, failureCb, options); 2390 * } 2391 * 2392 * @class storage 2393 * @param {Function} 2394 * successCallback success callback function. 2395 * @param {Function} 2396 * errorCallback failure callback function. 2397 * 2398 * @param {Object} options 2399 * <div align=left> 2400 * <table class="hcap_spec" width=400> 2401 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2402 * <tbody> 2403 * <tr><th>oldPath</th><th>{@link Storage.SCAP_URI}</th><th>URI to the original file (internal/usb/sdcard).</a></th><th>required</th></tr> 2404 * <tr class="odd"><tr><th>newPath</th><th>{@link Storage.SCAP_URI}</th><th>URI to the new file (internal/usb/sdcard).</a></th><th>required</th></tr> 2405 * </tbody> 2406 * </table> 2407 * </div> 2408 * 2409 * @returns 2410 * <p> 2411 * After the method is successfully executed, successCallback is called without any parameter.</br> 2412 * If an error occurs, errorCallback is called with errorCode and errorText. 2413 * To see how error codes are defined, check {@link Error.ERROR_CODE} 2414 * </p> 2415 * 2416 * @since 1.2 2417 */ 2418 Storage.prototype.moveFile = function (successCallback, errorCallback, options) { 2419 if (!options) { 2420 errorCallback({ 2421 errorCode: "BAD_PARAMETER", 2422 errorText: "options.path is a mandatory parameter" 2423 }); 2424 } 2425 else if (!isValidFileURI(options.oldPath)) { 2426 errorCallback({ 2427 errorCode: "BAD_PARAMETER", 2428 errorText: "options.oldpath is a mandatory parameter" 2429 }); 2430 } 2431 else if (!isValidFileURI(options.newPath)) { 2432 errorCallback({ 2433 errorCode: "BAD_PARAMETER", 2434 errorText: "options.newPath is a mandatory parameter" 2435 }); 2436 } 2437 else { 2438 try { 2439 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 2440 method: "fs/moveFile", 2441 parameters: { 2442 oldPath: options.oldPath, 2443 newPath: options.newPath 2444 }, 2445 onSuccess: function (result) { 2446 log("onSuccess"); 2447 2448 if (result.returnValue) { 2449 successCallback(); 2450 } 2451 else { 2452 log("FAILED: " + result.errorText); 2453 errorCallback({ 2454 errorCode: result.errorCode, 2455 errorText: result.errorText 2456 }); 2457 } 2458 }, 2459 onFailure: function (result) { 2460 log("onFailur"); 2461 log("FAILED: " + result.errorText); 2462 errorCallback({ 2463 errorCode: result.errorCode, 2464 errorText: result.errorText 2465 }); 2466 } 2467 }); 2468 } catch (err) { 2469 log("EXCEPTION" + err); 2470 errorCallback({ 2471 errorCode: 'STMF', 2472 errorText: 'Storage.moveFile() error is occured during operation.' 2473 }); 2474 } 2475 } 2476 }; 2477 2478 /** 2479 * 2480 * Unzip file. It should be compressed in PKI-ZIP format. 2481 * 2482 * @example 2483 * function unzipFile() { 2484 * var successCb = function (){ 2485 * console.log("Unzip File successful"); 2486 * }; 2487 * 2488 * var failureCb = function(cbObject){ 2489 * var errorCode = cbObject.errorCode; 2490 * var errorText = cbObject.errorText; 2491 * console.log( " Error Code [" + errorCode + "]: " + errorText); 2492 * }; 2493 * 2494 * var options = { 2495 * zipPath: 'file://internal/myFile.zip', 2496 * targetPath: 'file://internal/unzip/to/here', 2497 * }; 2498 * 2499 * var storage = new Storage(); 2500 * storage.unzipFile(successCb, failureCb, options); 2501 * } 2502 * 2503 * @class storage 2504 * @param {Function} 2505 * successCallback success callback function. 2506 * @param {Function} 2507 * errorCallback failure callback function. 2508 * 2509 * @param {Object} options 2510 * <div align=left> 2511 * <table class="hcap_spec" width=400> 2512 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2513 * <tbody> 2514 * <tr><th>zipPath</th><th>{@link Storage.SCAP_URI}</th><th>URI to the zip file (internal/usb/sdcard).</a></th><th>required</th></tr> 2515 * <tr class="odd"><tr><th>targetPath</th><th>{@link Storage.SCAP_URI}</th><th>URI to the target directory where the contents of the zip file will be stored. (internal/usb/sdcard)</a></th><th>required</th></tr> 2516 * </tbody> 2517 * </table> 2518 * </div> 2519 * 2520 * @returns 2521 * <p> 2522 * After the method is successfully executed, successCallback is called without any parameter. </br> 2523 * If an error occurs, errorCallback is called with errorCode and errorText. 2524 * To see how error codes are defined, check {@link Error.ERROR_CODE} 2525 * </p> 2526 * 2527 * @since 1.2 2528 */ 2529 Storage.prototype.unzipFile = function (successCallback, errorCallback, options) { 2530 if (!options) { 2531 errorCallback({ 2532 errorCode: "BAD_PARAMETER", 2533 errorText: "options.path is a mandatory parameter" 2534 }); 2535 } 2536 else if (!isValidFileURI(options.zipPath)) { 2537 errorCallback({ 2538 errorCode: "BAD_PARAMETER", 2539 errorText: "options.zipPath is a mandatory parameter" 2540 }); 2541 } 2542 else if (!isValidFileURI(options.targetPath)) { 2543 errorCallback({ 2544 errorCode: "BAD_PARAMETER", 2545 errorText: "options.targetPath is a mandatory parameter" 2546 }); 2547 } 2548 else { 2549 try { 2550 service.Request("luna://com.webos.service.commercial.signage.storageservice", { 2551 method: "fs/unzip", 2552 parameters: { 2553 zipPath: options.zipPath, 2554 targetPath: options.targetPath 2555 }, 2556 onSuccess: function (result) { 2557 log("onSuccess"); 2558 2559 if (result.returnValue) { 2560 successCallback(); 2561 } 2562 else { 2563 log("FAILED: " + result.errorText); 2564 errorCallback({ 2565 errorCode: result.errorCode, 2566 errorText: result.errorText 2567 }); 2568 } 2569 }, 2570 onFailure: function (result) { 2571 log("onFailure"); 2572 log("FAILED: " + result.errorText); 2573 errorCallback({ 2574 errorCode: result.errorCode, 2575 errorText: result.errorText 2576 }); 2577 } 2578 }); 2579 } catch (err) { 2580 log("EXCEPTION" + err); 2581 errorCallback({ 2582 errorCode: 'STUF', 2583 errorText: 'Storage.unzipFile() error is occured during operation.' 2584 }); 2585 } 2586 } 2587 }; 2588 2589 /** 2590 * Gets the MD5 hashing value of the input file. 2591 * @class Storage 2592 * @param {Function} successCallback success callback function. 2593 * @param {Function} errorCallback failure callback function. 2594 * @param {Object} options 2595 * <table class="hcap_spec" width=400> 2596 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2597 * <tbody> 2598 * <tr><th>filePath</th><th>String</th><th>Set input file path (file://internal/test.txt) </th><th>required</th></tr> 2599 * </tbody> 2600 * </table> 2601 * </div> 2602 * @return {Object} 2603 * <div align=left> 2604 * <table class="hcap_spec" width=400> 2605 * <tbody> 2606 * <thead><tr><th>Property</th><th>Type</th><th>Description</th></tr></thead> 2607 * <tr><th>md5hash</th><th>String</th><th>MD5 hash value</th></tr> 2608 * </tbody> 2609 * </table> 2610 * </div> 2611 * 2612 * @example 2613 * // Javascript code 2614 * function getMD5Hash () { 2615 * function successCb(cbObject) { 2616 * console.log("cbObject : " + JSON.stringify(cbObject)); 2617 * console.log("md5hash : " + cbObject.md5hash); 2618 * } 2619 * 2620 * function failureCb(cbObject) { 2621 * var errorText = cbObject.errorText; 2622 * console.log ("Error Code [" + errorCode + "]: " + errorText); 2623 * } 2624 * 2625 * var options = { filePath : true }; 2626 * var storage = new Storage(); 2627 * storage.getMD5Hash(successCb, failureCb, options); 2628 * } 2629 * @since 1.5 2630 */ 2631 Storage.prototype.getMD5Hash = function (successCallback, errorCallback, options) { 2632 2633 log("getMD5Hash: "); 2634 if (!(options && isValidFileURI(options.filePath))) { 2635 errorCallback({ 2636 errorCode: "BAD_PARAMETER", 2637 errorText: "options.filePath is a mandatory parameter" 2638 }); 2639 return; 2640 } 2641 2642 service.Request('luna://com.webos.service.commercial.signage.storageservice/', { 2643 method: 'fs/getMD5Hash', 2644 parameters: { 2645 filePath: options.filePath 2646 }, 2647 onSuccess: function (result) { 2648 if (typeof successCallback === 'function') { 2649 delete result.returnValue; 2650 successCallback(result); 2651 } 2652 }, 2653 onFailure: function (error) { 2654 log("getMD5Hash: onFailure"); 2655 delete error.returnValue; 2656 if (typeof errorCallback === 'function') { 2657 errorCallback(error); 2658 } 2659 } 2660 }); 2661 log("Storage.getMD5Hash Done"); 2662 }; 2663 2664 /** 2665 * Decrypt the input file. 2666 * @class Storage 2667 * @param {Function} successCallback success callback function. 2668 * @param {Function} errorCallback failure callback function. 2669 * @param {Object} options 2670 * <div align=left> 2671 * <table class="hcap_spec" width=400> 2672 * <thead><tr><th>Property</th><th>Type</th><th>Description</th><th>Required</th></tr></thead> 2673 * <tbody> 2674 * <tr><th>cipher_mode</th><th>String</th><th>Set cipher_mode (aes-128-cbc, aes-128-ecb, aes-192-cbc, aes-192-ecb, aes-256-cbc, aes-256-ecb) </th><th>required</th></tr> 2675 * <tr class="odd"><tr><th>password</th><th>String</th><th>Set password for decryption.<br></th><th>required</th></tr> 2676 * <tr><th>inputPath</th><th>String</th><th>Set input file path.</th><th>required</th></tr> 2677 * <tr class="odd"><tr><th>outputFileName</th><th>String</th><th>Set output file name.<br></th><th>required</th></tr> 2678 * </tbody> 2679 * </table> 2680 * </div> 2681 * @return <p>If the method is successfully executed, call the success callback function without a parameter.</br> 2682 * If an error occurs, failure callback function is called with failure callback object as a parameter.</p> 2683 * 2684 * @example 2685 * // Javascript code 2686 * function decryptFile () { 2687 * function successCb(cbObject) { 2688 * console.log("cbObject : " + JSON.stringify(cbObject)); 2689 * } 2690 * 2691 * function failureCb(cbObject) { 2692 * var errorText = cbObject.errorText; 2693 * console.log ("Error Code [" + errorCode + "]: " + errorText); 2694 * } 2695 * 2696 * var params = { 2697 * cipher_mode : "aes-256-cbc", 2698 * password : "test", 2699 * inputPath : "file://internal/test_enc.mp4", 2700 * outputFileName : "test.mp4" 2701 * }; 2702 * var storage = new Storage(); 2703 * storage.decryptFile(successCb, failureCb, params); 2704 * } 2705 * @since 1.5 2706 */ 2707 Storage.prototype.decryptFile = function (successCallback, errorCallback, options) { 2708 2709 log("decryptFile: "); 2710 2711 service.Request('luna://com.webos.service.commercial.signage.storageservice/', { 2712 method: 'fs/decryptFile', 2713 parameters: { 2714 cipher_mode: options.cipher_mode, 2715 password: options.password, 2716 inputPath: options.inputPath, 2717 outputFileName: options.outputFileName 2718 }, 2719 onSuccess: function (result) { 2720 if (typeof successCallback === 'function') { 2721 delete result.returnValue; 2722 successCallback(result); 2723 } 2724 }, 2725 onFailure: function (error) { 2726 log("decryptFile: onFailure"); 2727 delete error.returnValue; 2728 if (typeof errorCallback === 'function') { 2729 errorCallback(error); 2730 } 2731 } 2732 }); 2733 log("Storage.decryptFile Done"); 2734 }; 2735 2736 module.exports = Storage; 2737 }); 2738 2739 Storage = cordova.require('cordova/plugin/storage'); 2740