Skip to content

Instantly share code, notes, and snippets.

@volodymyrlut
Created June 24, 2015 12:35
Show Gist options
  • Save volodymyrlut/088bfd85a3380cd5725d to your computer and use it in GitHub Desktop.
Save volodymyrlut/088bfd85a3380cd5725d to your computer and use it in GitHub Desktop.
WattAttack.module("Entities", function(Entities, WattAttack, Backbone, Marionette, $, _){
var FileProtocol = {
deferedSendFiles: function(fileCollection){
console.log('uploading files here' + fileCollection.map(function(file){
return file.get('name');
}).join(','));
var req = [];
for (var index = 0; index < fileCollection.models.length; index++){
var data = new FormData();
var prefix = "files[0]";
data.append(prefix + "[name]", fileCollection.models[index].get('name'));
data.append(prefix + "[file]", fileCollection.models[index].get('jsFile'));
data.append(prefix + "[note]", fileCollection.models[index].get('note'));
req.push($.ajax({
url: "/api/"+ WattAttack.currentAPIVersion() + "/rides/upload",
type: "POST",
data: data,
processData: false,
contentType: false,
}));
}
return req;
},
};
// var FileProtocolMock = {
// mockFiles: [],
// deferedSendFiles: function(fileCollection){
// var self = this;
// console.log('uploading files ' + fileCollection.map(function(file){
// return file.get('name');
// }).join(','));
// var randomPeriod = Math.floor(Math.random() * 1000);
// var defer = $.Deferred();
// setTimeout(function(){
// if(Math.floor(Math.random() * 4) != 0){
// self.mockFiles = fileCollection.map(function(e){
// return {
// uuid: WattAttack.createUuid(),
// name: e.get('name'),
// status: 'processing',
// message: ''
// };
// });
// defer.resolve(self.mockFiles);
// }else
// defer.reject();
// }, randomPeriod);
// return defer;
// },
// deferedCheckFilesStatus: function (fileCollection){
// var self = this;
// function updateMockFiles(){
// _(self.mockFiles).where({status: 'processing'}).forEach(function(e){
// if(Math.floor(Math.random() * 4) == 0){
// if(Math.floor(Math.random() * 2) == 0){
// e.status = 'processed';
// } else{
// e.status = 'failed';
// e.message = 'the file had an evil format';
// }
// }
// });
// }
// var randomPeriod = Math.floor(Math.random() * 2000);
// var defer = $.Deferred();
// setTimeout(function(){
// updateMockFiles();
// console.log('checking files:' + JSON.stringify(self.mockFiles));
// if(Math.floor(Math.random() * 2) == 0){
// defer.resolve(self.mockFiles);
// }else
// defer.reject();
// }, randomPeriod);
// return defer;
// },
// };
//This is an abstract class
function PoolingFilesUploader(opts){
var fileProtocol = opts.fileProtocol;
var onPoolingResponse = opts.onPoolingResponse;
var onProcessingFinished = opts.onProcessingFinished;
var onRequestFailed = opts.onRequestFailed;
var onRequestSucceeded = opts.onRequestSucceeded;
var isLastResponse = opts.isLastResponse;
var poolingInterval = opts.poolingInterval ? opts.poolingInterval : 3000;
var timeout = opts.timeout ? opts.timeout : 3 * 60 * 1000;
var onTimeout = opts.onTimeout ? opts.onTimeout : opts.onRequestFailed;
var calcTimeout = opts.calcTimeout ? opts.calcTimeout : function(){return timeout;};
var dataSource = opts.dataSource;
var fileStack = {
rides: [{
}]
};
var intervalId;
var alreadyFinished;
var timeoutId;
var self = this;
function pool(uuid){
console.log("pool called");
console.log(uuid);
var defer = $.ajax({
url: "/api/"+ WattAttack.currentAPIVersion() + "/rides/status",
type: "POST",
data: JSON.stringify(fileStack),
dataType: 'json',
processData: false,
contentType: 'application/json',
});
defer.done(function(response){
console.log("- - - - - - > R E S P O N S E");
console.log(response);
onPoolingResponse(response);
if(isLastResponse(response) && !alreadyFinished){
alreadyFinished = true;
clearInterval(intervalId);
clearTimeout(timeoutId);
onProcessingFinished();
}
});
defer.promise();
}
this.cancel = function(){
clearInterval(intervalId);
alreadyFinished = true;
};
function internalOnTimeout(){
self.cancel();
onTimeout();
}
function startPooling(uuid){
fileStack.rides.push({uuid: uuid});
intervalId = setInterval(pool,poolingInterval);
timeoutId = setTimeout(internalOnTimeout, calcTimeout());
alreadyFinished = false;
}
this.startSending = function (request){
var defer = fileProtocol.deferedSendFiles(request);
var i = 0;
function sendOneByOne(){
if(i < defer.length){
defer[i].fail(onRequestFailed);
defer[i].done(function(response){
onRequestSucceeded(response);
startPooling(response[0].uuid);
i++;
sendOneByOne();
});
defer[i].promise();
}
}
sendOneByOne();
};
return this;
}
//this is a concretition
function FilesCollectionUpdater(filesCollection){
PoolingFilesUploader.call(this,{
fileProtocol: FileProtocol,
poolingInterval: 2000,
dataSource: filesCollection,
calcTimeout: function(){
return filesCollection.size() * 60 * 1000;
},
onPoolingResponse: function(response){
filesCollection.trigger('upload:pooling:update', response);
},
onRequestSucceeded: function(response){
filesCollection.trigger('upload:start', response);
},
onProcessingFinished: function(){
filesCollection.trigger('upload:success');
},
onRequestFailed: function(){
filesCollection.trigger('upload:fail');
},
onTimeout: function(){
filesCollection.trigger('upload:timeout');
},
isLastResponse: function(res){
return res.every(function(file){
return file.status == 'processed' || file.status == 'failed';
});
}
});
}
// subclass extends superclass
FilesCollectionUpdater.prototype = Object.create(PoolingFilesUploader.prototype);
FilesCollectionUpdater.prototype.constructor = FilesCollectionUpdater;
function realUploadFile(){
var self = this;
console.log('uploading files here' + this.map(function(file){
return file.get('name');
}).join(','));
return $.ajax({
url: "/upload",
type: "POST",
data: self.toFormData(),
processData: false,
contentType: false,
});
}
Entities.RideFile = Backbone.Model.extend({
defaults: {
name: "",
size: 0,
note: "",
jsFile: null
},
validate: function(attrs, options) {
var errors = {};
},
updateFromResponse: function(responseModel){
this.set({'message': responseModel.message});
this.set({'uuid': responseModel.uuid});
this.set({'status': responseModel.status});
}
});
Entities.RideFileCollection = Backbone.Collection.extend({
model: Entities.RideFile,
comparator: "name",
initialize: function(){
this.uploader = new FilesCollectionUpdater(this);
},
toFormData: function(options){
console.log("FORMING DATA");
var data = new FormData();
return this.reduce(function(data, file, index){
console.log("uploading " + file.get('name'));
var prefix = "files["+ index+"]";
data.append(prefix + "[name]", file.get('name'));
data.append(prefix + "[file]", file.get('jsFile'));
data.append(prefix + "[note]", file.get('note'));
return data;
}, data);
},
submit: function(){
this.uploader.startSending(this);
this.on('upload:start', this.onUploadStart, this);
this.on('upload:pooling:update', this.onUploadPoolingUpdate, this);
},
onUploadStart: function(response){
var self = this;
response.forEach(function(responseModel){
var model = self.filter(function(f){
var lastfileName = f.get('jsFile').name.split(/[\\\/]/).pop();
return lastfileName == responseModel.file_name;
})[0];
model.updateFromResponse(responseModel);
});
},
onUploadPoolingUpdate: function(response){
var self = this;
console.log("RESPONSED BUG");
console.log(response);
response.forEach(function(responseModel){
var model = self.where({uuid: responseModel.uuid})[0];
model.updateFromResponse(responseModel);
});
}
});
var API = {};
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment