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