(function(global){ class StatusItem extends Observable{ constructor(type){ super(); this._status = 'new'; this._type = type; this._id = Math.random(); this._errorMessage = null; } getId(){ return this._id; } getLabel(){ } getType(){ return this._type; } getStatus(){ return this._status; } setStatus(status){ this._status = status; this.notify('status'); } updateRepositoryId(repositoryId){ this._repositoryId = repositoryId; } getErrorMessage(){ return this._errorMessage || ''; } onError(errorMessage){ this._errorMessage = errorMessage; this.setStatus('error'); } process(completeCallback){ this._doProcess(completeCallback); } abort(completeCallback){ if(this._status !== 'loading') return; this._doAbort(completeCallback); } } class UploadItem extends StatusItem{ constructor(file, targetNode, relativePath = null){ super('file'); this._file = file; this._status = 'new'; this._progress = 0; this._targetNode = targetNode; this._repositoryId = global.pydio.user.activeRepository; this._relativePath = relativePath; } getMqConfigs(){ return global.pydio.getPluginConfigs('mq'); } getFile(){ return this._file; } getSize(){ return this._file.size; } getLabel(){ return this._relativePath ? this._relativePath : this._file.name; } getProgress(){ return this._progress; } setProgress(newValue, bytes = null){ this._progress = newValue; this.notify('progress', newValue); if(bytes !== null) { this.notify('bytes', bytes); } } getRelativePath(){ return this._relativePath; } buildQueryString(){ let fullPath = this._targetNode.getPath(); if(this._relativePath) { fullPath += PathUtils.getDirname(this._relativePath); } let currentRepo = global.pydio.user.activeRepository; let queryString = '&get_action=upload&xhr_uploader=true&dir=' + encodeURIComponent(fullPath); let dataModel = global.pydio.getContextHolder(); let nodeName = PathUtils.getBasename(this._file.name); var newNode = new AjxpNode(fullPath+"/"+nodeName); if(this._file.size){ newNode.getMetadata().set("filesize", this._file.size); } try{ let params = null; if(currentRepo !== this._repositoryId) { params = {tmp_repository_id:this._repositoryId}; } dataModel.applyCheckHook(newNode, params); }catch(e){ throw new Error(global.pydio.MessageHash['html_uploader.3']); } let overwriteStatus = UploaderConfigs.getInstance().getOption("DEFAULT_EXISTING", "upload_existing"); if(overwriteStatus === 'rename'){ queryString += '&auto_rename=true'; }else if(overwriteStatus === 'alert' && !this._relativePath && currentRepo === this._repositoryId){ if(dataModel.fileNameExists(nodeName, false, this._targetNode)){ if(!global.confirm(global.pydio.MessageHash[124])){ throw new Error(global.pydio.MessageHash[71]); } } } if(currentRepo !== this._repositoryId){ queryString += '&tmp_repository_id=' + this._repositoryId; } return queryString; } _parseXHRResponse(){ if(!this.xhr) return; if (this.xhr.responseXML){ var result = PydioApi.getClient().parseXmlMessage(this.xhr.responseXML); if(!result) this.onError('Empty response'); }else if (this.xhr.responseText && this.xhr.responseText != 'OK') { this.onError('Unexpected response: ' + this.xhr.responseText); } } _doProcess(completeCallback){ let complete = function(){ this.setStatus('loaded'); this._parseXHRResponse(); completeCallback(); }.bind(this); let error = function(){ this.setStatus('error'); completeCallback(); }.bind(this); let progress = function(computableEvent){ let percentage = Math.round((computableEvent.loaded * 100) / computableEvent.total); let bytesLoaded = computableEvent.loaded; this.setProgress(percentage, bytesLoaded); }.bind(this); this.setStatus('loading'); let maxUpload = parseFloat(UploaderConfigs.getInstance().getOption('UPLOAD_MAX_SIZE')); let queryString; try{ UploaderConfigs.getInstance().extensionAllowed(this); queryString = this.buildQueryString(); }catch(e){ this.onError(e.message); completeCallback(); return; } // Checks applied. if(this.getMqConfigs().get('UPLOAD_ACTIVE')){ this.tryAlternativeUpload(complete, progress, function(){ // Failed, switch back to normal upload. if(this.getSize() > maxUpload){ this.onError(global.pydio.MessageHash[211]); completeCallback(); return; } this.xhr = PydioApi.getClient().uploadFile(this._file,'userfile_0',queryString,complete,error,progress); }.bind(this)); }else{ if(this.getSize() > maxUpload){ this.onError(global.pydio.MessageHash[211]); completeCallback(); return; } this.xhr = PydioApi.getClient().uploadFile(this._file,'userfile_0',queryString,complete,error,progress); } } _doAbort(completeCallback){ if(this.xhr){ try{ this.xhr.abort(); }catch(e){} } } tryAlternativeUpload(completeCallback, progressCallback, errorCallback){ let configs = this.getMqConfigs(); var secure = configs.get("BOOSTER_MAIN_SECURE"); if(configs.get("BOOSTER_UPLOAD_ADVANCED") && configs.get("BOOSTER_UPLOAD_ADVANCED")['booster_upload_advanced'] === 'custom' && configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_SECURE']){ secure = configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_SECURE']; } var host = configs.get("BOOSTER_MAIN_HOST"); if(configs.get("BOOSTER_UPLOAD_ADVANCED") && configs.get("BOOSTER_UPLOAD_ADVANCED")['booster_upload_advanced'] === 'custom' && configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_HOST']){ host = configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_HOST']; } var port = configs.get("BOOSTER_MAIN_PORT"); if(configs.get("BOOSTER_UPLOAD_ADVANCED") && configs.get("BOOSTER_UPLOAD_ADVANCED")['booster_upload_advanced'] === 'custom' && configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_PORT']){ port = configs.get("BOOSTER_UPLOAD_ADVANCED")['UPLOAD_PORT']; } let fullPath = this._targetNode.getPath(); if(this._relativePath) { fullPath += PathUtils.getDirname(this._relativePath); } fullPath += '/' + encodeURI(PathUtils.getBasename(this._file.name)); let url = "http"+(secure?"s":"")+"://"+host+":"+port+"/"+configs.get("UPLOAD_PATH")+"/"+this._repositoryId + fullPath; let queryString = ''; let overwriteStatus = UploaderConfigs.getInstance().getOption("DEFAULT_EXISTING", "upload_existing"); if(overwriteStatus === 'rename') { queryString += 'auto_rename=true'; } try{ this.xhr = PydioApi.getClient().uploadFile(this._file,'userfile_0',queryString,completeCallback,errorCallback,progressCallback, url, {withCredentials:true}); }catch(e){ errorCallback(); } } } class FolderItem extends StatusItem{ constructor(path, targetNode){ super('folder'); this._path = path; this._targetNode = targetNode; } getPath(){ return this._path; } getLabel(){ return PathUtils.getBasename(this._path); } _doProcess(completeCallback){ let fullPath = this._targetNode.getPath() + this._path; let params = { get_action: 'mkdir', dir: PathUtils.getDirname(fullPath), dirname:PathUtils.getBasename(fullPath), ignore_exists:true, }; if(this._repositoryId && global.pydio.user.activeRepository !== this._repositoryId) { params['tmp_repository_id'] = this._repositoryId; } PydioApi.getClient().request(params, function(t){ this.setStatus('loaded'); var result = PydioApi.getClient().parseXmlMessage(t.responseXML); if(!result) this.onError('Empty response'); completeCallback(); }.bind(this)); } _doAbort(completeCallback){ if(global.console) global.console.log(global.pydio.MessageHash['html_uploader.6']); } } class UploadTask extends PydioTasks.Task{ constructor(){ super({ id : 'local-upload-task', userId : global.pydio.user.id, wsId : global.pydio.user.activeRepository, flags : PydioTasks.Task.FLAG_HAS_PROGRESS|PydioTasks.Task.FLAG_STOPPABLE, label : global.pydio.MessageHash['html_uploader.7'], status : PydioTasks.Task.STATUS_COMPLETE, statusMessage : '' }); } setProgress(progress){ this._internal['progress'] = progress; this.updateStatus(PydioTasks.Task.STATUS_RUNNING); } setPending(queueSize){ this._internal['statusMessage'] = global.pydio.MessageHash['html_uploader.1'].replace('%s', queueSize); this.updateStatus(PydioTasks.Task.STATUS_PENDING); } setRunning(queueSize){ this._internal['statusMessage'] = global.pydio.MessageHash['html_uploader.2'].replace('%s', queueSize); this.updateStatus(PydioTasks.Task.STATUS_RUNNING); } setIdle(){ this._internal['statusMessage'] = ''; this.updateStatus(PydioTasks.Task.STATUS_COMPLETE); } updateStatus(status){ this._internal['status'] = status; this.notifyMainStore(); } notifyMainStore(){ PydioTasks.Store.getInstance().notify("tasks_updated"); } hasOpenablePane(){ return true; } openDetailPane(){ global.pydio.Controller.fireAction("upload"); } static getInstance(){ if(!UploadTask.__INSTANCE) { UploadTask.__INSTANCE = new UploadTask(); PydioTasks.Store.getInstance().enqueueLocalTask(UploadTask.__INSTANCE); } return UploadTask.__INSTANCE; } } class UploaderStore extends Observable{ constructor(){ super(); this._folders = []; this._uploads = []; this._processing = []; this._processed = []; this._errors = []; // Todo this._queueCounter = 0; this._maxQueueSize = 2; } recomputeGlobalProgress(){ let totalCount = 0; let totalProgress = 0; this._uploads.concat(this._processing).concat(this._processed).forEach(function(item){ if(!item.getProgress) return; totalCount += item.getSize(); totalProgress += item.getProgress() * item.getSize() / 100; }); let progress; if(!totalCount) { progress = 0; }else{ progress = totalProgress / totalCount * 100; } return progress; } getAutoStart(){ return UploaderConfigs.getInstance().getOptionAsBool("DEFAULT_AUTO_START", "upload_auto_send"); } getAutoClose(){ return UploaderConfigs.getInstance().getOptionAsBool("DEFAULT_AUTO_CLOSE", "upload_auto_close"); } pushFolder(folderItem){ if(!this.getQueueSize()){ this._processed = []; } this._folders.push(folderItem); UploadTask.getInstance().setPending(this.getQueueSize()); if(this.getAutoStart() && !this._processing.length) { this.processNext(); } // Autostart with queue was empty before this.notify('update'); this.notify('item_added', folderItem); } pushFile(uploadItem){ if(!this.getQueueSize()){ this._processed = []; } this._uploads.push(uploadItem); UploadTask.getInstance().setPending(this.getQueueSize()); uploadItem.observe("progress", function(){ let pg = this.recomputeGlobalProgress(); UploadTask.getInstance().setProgress(pg); }.bind(this)); if(this.getAutoStart() && !this._processing.length) { this.processNext(); } // Autostart with queue was empty before this.notify('update'); this.notify('item_added', uploadItem); } log(){ } processQueue(){ let next = this.getNext(); while(next !== null){ next.process(function(){ if(next.getStatus() === 'error') { this._errors.push(next); } else { this._processed.push(next); } this.notify("update"); }.bind(this)); next = this.getNext(); } } getQueueSize(){ return this._folders.length + this._uploads.length + this._processing.length; } clearAll(){ this._folders = []; this._uploads = []; this._processing = []; this._processed = []; this._errors = []; this.notify('update'); UploadTask.getInstance().setIdle(); } processNext(){ let processable = this.getNext(); if(processable){ this._processing.push(processable); UploadTask.getInstance().setRunning(this.getQueueSize()); processable.process(function(){ this._processing = LangUtils.arrayWithout(this._processing, this._processing.indexOf(processable)); if(processable.getStatus() === 'error') { this._errors.push(processable) } else { this._processed.push(processable); } this.processNext(); this.notify("update"); }.bind(this)); }else{ UploadTask.getInstance().setIdle(); if(this.hasErrors()){ if(!pydio.getController().react_selector){ global.pydio.getController().fireAction("upload"); } }else if(this.getAutoClose()){ this.notify("auto_close"); } } } getNext(){ if(this._folders.length){ return this._folders.shift(); } if(this._uploads.length){ return this._uploads.shift(); } } stopOrRemoveItem(item){ item.abort(); ['_uploads', '_folders', '_processing', '_processed', '_errors'].forEach(function(key){ let arr = this[key]; if(arr.indexOf(item) !== -1) { this[key] = LangUtils.arrayWithout(arr, arr.indexOf(item)); } }.bind(this)); this.notify("update"); } getItems(){ return { processing: this._processing, pending: this._folders.concat(this._uploads), processed: this._processed, errors: this._errors }; } hasErrors(){ return this._errors.length ? this._errors : false; } static getInstance(){ if(!UploaderStore.__INSTANCE){ UploaderStore.__INSTANCE = new UploaderStore(); } return UploaderStore.__INSTANCE; } handleFolderPickerResult(files, targetNode){ var folders = {}; for(var i=0;i