Source: protocol/local.js

/**
 * Mobizen - Mobizen/Socket/Channel/Local
 *
 * IMPORTANT NOTE: This file is licensed only for use in providing the RSUPPORT services,
 *
 * @copyright 2015 RSUPPORT CO., LTD. All rights reserved.
 * @license Dedicated to the public domain.
 * @author Joon Kyoung <firejune@gmail.com>
 *
 */

(function(exports) {
  "use strict";

  /** @typedef {Mobizen} */
  var Mobizen = exports.Mobizen || (exports.Mobizen = {});

  /**
   * @constructs Local
   * @memberof Mobizen.Socket.Channel
   * @extends Mobizen.Socket.Channel
   * @param {Mobizen.Socket} socket - A provider of Mobizen/Socket API.
   *
   */
  function Local(socket) {
    this.super_.call(this, socket, 'local');
    //this.on('request', this.send.bind(this));
  }

  Mobizen.Inherits(Local, Mobizen.Channel, /** @lends Mobizen.Socket.Channel.Local# */ {
    /**
     * @method
     */
    start: function() {
      this.socket.data.request('login.local', {
        type: 2
      })
        .on('end'
        /**
         * @listens Mobizen.Socket.Channel.Data#login․local․end
         * @param {object} data
         * @memberof Mobizen.Socket.Channel.Local~
         */
        , function onendloginlocal(data) {
          var params = {
            userid: this.socket.params.user.id,
            // location.host for apk ver 2.0.3.23
            // 주소 이상하게 넘어오면 apk 런처 확인할 것!
            server: this.socket.specific.authRes.webAddress || location.host,
            // extensionId for api ver 2.0.5.0
            connectid: this.socket.params.localSessionKey,
            connectedmode: this.socket.type,
            connectedtype: this.socket.specific.connectedType,
            accounttype: this.socket.params.user.type, // parseInt
            authurl: this.socket.url('/' + data.lid)
          };

          //console.debug('Local.start', params);

          this.send('auth', params);
        }.bind(this));
    },

    /**
     * @param {string} cmd
     * @param {object} data
     * @return {object} data of struct
     * @exception Will throw an error if unknown command
     */
    send: function(cmd, data) {
      var topic;

      switch(cmd) {
        // 209-0 Request file list
        case 'files': topic = 'File-Path'; break;
        // 209-3 Request delete file
        case 'file.delete': topic = 'File-DeleteRequest'; break;
        // 209-5 Request change file name
        case 'file.rename': topic = 'File-RenameRequest'; break;
        // 209-7 Request create a new folder
        case 'file.create': topic = 'File-MakeFolderRequest'; break;
        // 209-12 Send find file start
        case 'file.find': topic = 'File-Find'; break;
        // 209-51 Request cancel find file
        case 'file.find.cancel': topic = 'File-Stop'; break;
        // 209-91 Request upload list to pc
        case 'file.upload': topic = 'File-UploadListRequest'; break;
        // 209-93 Request download list to pc
        case 'file.download': topic = 'File-DownloadListRequest'; break;
        // 209-107 Send cancel of file tasks
        case 'file.cancel': topic = 'File-CancelRequest'; break;

        // 220-100 Request local auth info
        case 'auth':  topic = 'Remote-LocalInfoRequest'; break;

        // 237-2 Send restore or backup list download
        case 'restore.download':
        case 'backup.download': topic = 'Archive-DownloadStart'; break;
        // 237-8 Send restore start
        case 'restore.start': topic = 'Archive-RestoreRequest'; break;
        // 237-10 Send restore or backup cancel
        case 'restore.cancel':
        case 'backup.cancel': topic = 'Archive-Cancel'; break;
        // 237-11 Request backup folder info
        case 'backup.folder': topic = 'Archive-BackupFolderRequest'; break;
        // 237-13 Request restore folder info
        case 'restore.folder': topic = 'Archive-RestoreFolderRequest'; break;
        // 237-15 Send selected folders
        case 'restore.selected': topic = 'Archive-SelectedFolder'; break;
        // 237-16 Send restore option
        case 'restore.option': topic = 'Archive-Option'; break;
        // 237-30 Send restore info
        case 'restore.info': topic = 'Archive-FolderInfoRequest'; break;

        // 242-0 Request media files
        case 'media.photos':
        case 'media.videos':
        case 'media.music': topic = 'Media-DataRequest'; this.listener = cmd; break;
        // 242-4 Request preview image of media
        case 'media.thumbnail': topic = 'Media-PreviewRequest'; break;
        // 242-30 Request database sync
        case 'media.sync': topic = 'Media-Sync'; break;
        // 242-100 Request media search
        case 'media.search': topic = 'Media-SingleDataRequest'; break;
        // 242-102 Request media access
        case 'media.access': topic = 'Media-Access'; break;
      }

      if (topic !== undefined) {
        topic = topic.split('-');
        return this.protocol.request(this.name, topic[0], topic[1], data);
      } else {
        return new Error('Unknown command:', cmd);
      }
    },

    /**
     * @fires Mobizen(Service)#connect․local
     * @param {object} payload
     * @param {object} data
     */
    receive: function(payload, data) {
      var closed = false
        , message = payload.msgText;

      switch(payload.typeText) {
        // 209 File
        case 'File': switch(message) {
          // 1 Response file list
          case 'PathList':
            /**
             * @event Mobizen.Socket.Channel.Local#file․external․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            closed = this.task('file.external', 'data', data);
            /**
             * @event Mobizen.Socket.Channel.Local#files․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            !closed && this.task('files', 'data', data);
            break;

          // 2 Receive file list end
          case 'PathListEnd':
            /**
             * @event Mobizen.Socket.Channel.Local#file․external․end
             * @type {Mobizen.Event}
             */
            closed = this.task('file.external', 'destroy');
            /**
             * @event Mobizen.Socket.Channel.Local#files․end
             * @type {Mobizen.Event}
             */
            !closed && this.task('files', 'destroy');
            break;

          // 4 Response delete file
          case 'Delete':
            /**
             * @event Mobizen.Socket.Channel.Local#file․delete․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.delete', 'data', data);
            break;

          // 6 Response change file name
          case 'Rename':
            /**
             * @event Mobizen.Socket.Channel.Local#file․rename․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.rename', 'data', data);
            break;

          // 8 Response create folder result
          case 'MakeFolder':
            /**
             * @event Mobizen.Socket.Channel.Local#file․create․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.create', 'data', data);
            break;

          // 13 Receive find file data
          case 'FindList':
            data.$channel = 'local';
            /**
             * @event Mobizen.Socket.Channel.Local#file․find․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.find', 'data', data);
            break;

          // 14 Receive find file end
          case 'FindListEnd':
            /**
             * @event Mobizen.Socket.Channel.Local#file․find․end
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.find', 'destroy', data);
            break;

          // 92 Response the result of upload list
          case 'UploadList':
            /**
             * @event Mobizen.Socket.Channel.Local#file․upload․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.upload', 'data', data);
            break;

          // 94 Response the result of download list
          case 'DownloadList':
            /**
             * @event Mobizen.Socket.Channel.Local#file․download․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.download', 'data', data);
            break;

          // 102 Receive file copy/move result
          case 'CopyMove':
            /**
             * @event Mobizen.Socket.Channel.Local#file․copy․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.copy', 'data', data);
            /**
             * @event Mobizen.Socket.Channel.Local#file․move․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('file.move', 'data', data);
            break;

          // 103 Receive file transfer start
          case 'TransferStart':
          // 104 Receive file transfer position
          case 'TransferPosition':
          // 105 Receive file transfer complete
          case 'TransferComplete':
          // 106 Receive file transfer end
          case 'TransferEnd':
            /**
             * @event Mobizen.Socket.Channel.Local#file․upload․data
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            /**
             * @event Mobizen.Socket.Channel.Local#file․download․data
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            this.task('file.' + this.file.mode, 'data', data, message.replace('Transfer', ''));
            break;

          // 108 Receive file transfer cancel
          case 'Cancel':
            /**
             * @event Mobizen.Socket.Channel.Local#file․upload․cancel
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            /**
             * @event Mobizen.Socket.Channel.Local#file․download․cancel
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            this.task('file.' + this.file.mode, 'cancel', data, message);
            break;

          // 109 Receive error of not enough space
          case 'NotEnoughSpace':
          // 110 Receive error of not exist file
          case 'NotExistFile':
          // 111 Receive unknown error
          case 'Error':
            /**
             * @event Mobizen.Socket.Channel.Local#file․upload․error
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            /**
             * @event Mobizen.Socket.Channel.Local#file․download․error
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} message
             */
            this.task('file.' + this.file.mode, 'error', data, message);
            break;

          default: this.error(payload, data);
        }
        break;

        // 220 Remote
        case 'Remote': switch(message) {
          // 101 Response the result of local info
          case 'LocalInfo':
            /** @type {boolean} */
            this.started = true;

            /**
             * @event Mobizen(Service)#connect․local
             * @type {Mobizen.Event}
             * @param {objet} data
             */
            this.socket.message("connect.local", data);
            break;

          default: this.error(payload, data);
        }
        break;

        // 235 Notify
        case 'Notify': switch(message) {
          // 10 Receive on delete a file of media
          case 'DeleteMedia':

            this.task('notify', 'data', message, {
              $channel: 'local',
              items: data.ids || data.items,
              kind: data.type
            });

            break;

          // 8-1 Receive on a new photo item added
          case 'Photo':
          // 8-2 Receive on new video item added
          case 'Video':
          // 8-3 Receive on a new music item added
          case 'Music':
            data.$channel = 'local';
            /**
             * @event Mobizen.Socket.Channel.Local#notify․data
             * @type {Mobizen.Event}
             * @param {string} message
             * @param {object} data
             */
            this.task('notify', 'data', message, data);
            break;

          // 27 Receive on media indexing complete of plug-in
          case 'IndexingComplete':
            this.socket.data.task('notify', 'data', message, data);
            break;

          default: this.error(payload, data);
        }
        break;

        // 237 Archive
        case 'Archive': switch(message) {
          // 9 Response the result of restore
          case 'Restore':
            /**
             * @event Mobizen.Socket.Channel.Local#restore․start
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('restore', 'start', data);
            break;

          // 3 Receive backup file count
          case 'DownloadCount':
          // 4 Receive current file transfer info
          case 'DownloadItemInfo':
          // 5 Receive current file transfer position
          case 'DownloadItemPosition':
          // 6 Receive current file transfer end
          case 'DownloadItemEnd':
          // 7 Receive file transfer end
          case 'DownloadEnd':
            /**
             * @event Mobizen.Socket.Channel.Local#backup․update
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} type
             * @param {string} message
             */
            this.task('backup', 'update', data, 'backup', message.replace('Download', ''));
            break;

          // 12 Response the result of backup folders
          case 'BackupFolder':
            /**
             * @event Mobizen.Socket.Channel.Local#backup․folder
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} type
             */
            this.task('backup', 'folder', data, 'backup');
            break;

          // 14 Response the result of restore folders
          case 'RestoreFolder':
            /**
             * @event Mobizen.Socket.Channel.Local#restore․folder
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} type
             */
            this.task('restore', 'folder', data, 'restore');
            break;

          // 31 Response backup folders info
          case 'FolderInfo':
            /**
             * @event Mobizen.Socket.Channel.Local#restore․info
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} type
             */
            this.task('restore', 'info', data, 'restore');
            break;

          // 20 Receive an error of not enough space
          case 'NotEnoughSpace':
          // 100 Receive an error of unknown
          case 'Error':
            /**
             * @event Mobizen.Socket.Channel.Local#backup․error
             * @type {Mobizen.Event}
             * @param {object} data
             * @param {string} type
             * @param {string} message
             */
            this.task('backup', 'error', data, 'backup', message);
            break;

          // 200 Receive restore terminate
          case 'Terminate':
            /**
             * @event Mobizen.Socket.Channel.Local#backup․end
             * @type {Mobizen.Event}
             * @param {string} type
             */
            this.task('backup', 'end', 'backup');
            this.socket.data.send('backup.end');
            break;

          default: this.error(payload, data);
        }
        break;

        // 242 Media
        case 'Media': switch(message) {
          // 1 Response total count of media
          case 'Data':
          // 2-1 Receive a photo data
          case 'Photo':
          // 2-2 Receive a video data
          case 'Video':
          // 2-3 Receive a music data
          case 'Music':
          // 3 Receive media data end
          case 'DataEnd':
          // 10 Receive an error
          case 'Error':

            var listener = {
              'Photo': 'media.photos',
              'Video': 'media.videos',
              'Music': 'media.music'
            }[message] || this.listener
            , event = {
              'Data': 'start',
              'DataEnd': 'end',
              'Error': 'error'
            }[message] || 'data';

            /**
             * @event Mobizen.Socket.Channel.Local#media․photos․error
             * @type {Mobizen.Event}
             * @param {string} type
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․videos․error
             * @type {Mobizen.Event}
             * @param {string} type
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․music․error
             * @type {Mobizen.Event}
             * @param {string} type
             */
            if (event == 'error') {
              return this.task(listener, 'error', 'local');
            }

            /**
             * @event Mobizen.Socket.Channel.Local#media․photos․end
             * @type {Mobizen.Event}
             * @param {string} type
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․videos․end
             * @type {Mobizen.Event}
             * @param {string} type
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․music․end
             * @type {Mobizen.Event}
             * @param {string} type
             */
            if (event == 'end') {
              return this.task(listener, 'destroy', 'local');
            }

            data.$channel = 'local';
            /**
             * @event Mobizen.Socket.Channel.Local#media․photos․start
             * @type {Mobizen.Event}
             * @param {object} data
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․videos․start
             * @type {Mobizen.Event}
             * @param {object} data
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․music․start
             * @type {Mobizen.Event}
             * @param {object} data
             */

            /**
             * @event Mobizen.Socket.Channel.Local#media․photos․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․videos․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            /**
             * @event Mobizen.Socket.Channel.Local#media․music․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task(listener, event, data);

            // FIXED: DataEnd event fired on wrong module
            if (data && data.kind) {
              this.listener = {
                '1': 'media.photos',
                '2': 'media.videos',
                '3': 'media.music'
              }[data.kind];
            }
            break;

          // 5 Response a data of media preview
          case 'Preview':
          // 11 Receive preview error
          case 'PreviewError':
            if (message == 'Preview') data.thumbnail = true;
            /**
             * @event Mobizen.Socket.Channel.Local#media․thumbnail․end
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('preview.' + data.kind + '-' + data.id, 'destroy', data);
            break;

          // 101 Response the single data of media
          case 'SingleData':
            data.$channel = 'local';
            /**
             * @event Mobizen.Socket.Channel.Local#media․search․data
             * @type {Mobizen.Event}
             * @param {object} data
             */
            this.task('media.search', 'data', data);
            break;

          default: this.error(payload, data);
        }
        break;

        default: this.error(payload, data);
      }
    },

    /**
     * @param {object} data
     * @return {Mobizen.Socket.Channel~Task} event emmiter
     */
    backup: function(data) {
      console.log('Local.backup');

      // this packet is send to data channel
      this.socket.data.send('backup.info', data);

      return (
        this.tasks.backup = this.sequence(null, {
          type: 'stream',
          cancel: 'backup.cancel'
        })
          .on('start'
          /**
           * @listens Mobizen.Socket.Channel.Local#backup․start
           * @memberof Mobizen.Socket.Channel.Local~
           * @param {object} list
           */
          , function onstartbackup(list) {
            this.send('backup.download', list);
          }.bind(this))
      );
    },

    /**
     * @return {Mobizen.Socket.Channel~Task} event emmiter
     */
    restore: function() {
      console.log('Local.restore');

      return (
        this.tasks.restore = this.sequence('restore.folder', {
          type: 'stream',
          cancel: function() {
            this.socket.data.send('restore.cancel');
            this.send('restore.cancel');
          }.bind(this)
        }).
          on('start'
          /**
           * @listens Mobizen.Socket.Channel.Local#restore․start
           * @memberof Mobizen.Socket.Channel.Local~
           * @param {object} list
           */
          , function onstartrestore(list) {
            //console.log('start', list);

            var data = {};
            for (var name in list.backupListFile) {
              data['restoreOption' + capitalize(name)] = 0;
            }

            this.socket.data.send('restore.option', data);
            this.send('restore.option', data);

            var transport = this.socket.transports[this.socket.type];
            this.send('restore.download', {
              ip: transport.http,
              port: transport.port
            });
          }.bind(this))
      );
    }
  });


  /**
   * Inner functions
   */

  /**
   * @memberof Mobizen.Socket.Channel.Local~
   * @param {string} str
   * @return {string} capitalized
   */
  function capitalize(str) {
    var arr = str.split(/\s|-/);

    str = '';

    for (var i = 0; i < arr.length; i++) {
      str += arr[i].charAt(0).toUpperCase() + arr[i].slice(1);
    }

    return str;
  }

  /*
   * Exporting modules
   */

  Mobizen.Channel.Local = Local;

})(this);
comments powered by Disqus