Initial commit
This commit is contained in:
260
lib/assets/javascripts/builder/data/upload-model.js
Executable file
260
lib/assets/javascripts/builder/data/upload-model.js
Executable file
@@ -0,0 +1,260 @@
|
||||
var _ = require('underscore');
|
||||
var Backbone = require('backbone');
|
||||
var UploadConfig = require('builder/config/upload-config');
|
||||
var Utils = require('builder/helpers/utils.js');
|
||||
var moment = require('moment');
|
||||
require('backbone-model-file-upload');
|
||||
|
||||
/**
|
||||
* Model that allows uploading files to CartoDB endpoints.
|
||||
*
|
||||
* NOTE: this model extends Backbone.Model instead of Backbone.Model, because
|
||||
* it's required for the vendor/backbone-model-file-upload.
|
||||
*/
|
||||
module.exports = Backbone.Model.extend({
|
||||
url: function () {
|
||||
var baseUrl = this._configModel.get('base_url');
|
||||
return baseUrl + '/api/v1/imports';
|
||||
},
|
||||
|
||||
fileAttribute: 'filename',
|
||||
|
||||
defaults: {
|
||||
type: '',
|
||||
value: '',
|
||||
interval: 0,
|
||||
privacy: '',
|
||||
progress: 0,
|
||||
state: 'idle',
|
||||
service_item_id: '',
|
||||
service_name: '',
|
||||
option: '',
|
||||
content_guessing: true,
|
||||
type_guessing: true,
|
||||
create_vis: true
|
||||
},
|
||||
|
||||
initialize: function (attrs, opts) {
|
||||
if (!opts.userModel) throw new Error('userModel is required');
|
||||
if (!opts.configModel) throw new Error('configModel is required');
|
||||
|
||||
this._userModel = opts.userModel;
|
||||
this._configModel = opts.configModel;
|
||||
this._initBinds();
|
||||
// We need to validate entry attributes
|
||||
this._validate(this.attributes, { validate: true });
|
||||
},
|
||||
|
||||
setUpload: function (d) {
|
||||
this.set(d, {
|
||||
validate: true
|
||||
});
|
||||
},
|
||||
|
||||
isValidToUpload: function () {
|
||||
return this.get('value') && this.get('state') !== 'error';
|
||||
},
|
||||
|
||||
setFresh: function (d) {
|
||||
if (d && !_.isEmpty(d)) {
|
||||
// Set upload properties except create_vis (defined when created)
|
||||
this.set(_.omit(d, 'create_vis'));
|
||||
} else {
|
||||
this.clear();
|
||||
}
|
||||
},
|
||||
|
||||
_initBinds: function () {
|
||||
this.bind('progress', function (progress) {
|
||||
this.set({
|
||||
progress: progress * 100,
|
||||
state: 'uploading'
|
||||
});
|
||||
}, this);
|
||||
|
||||
this.bind('change:value', function () {
|
||||
if (this.get('state') === 'error') {
|
||||
this.set({ state: 'idle' });
|
||||
this.unset('get_error_text', { silent: true });
|
||||
}
|
||||
}, this);
|
||||
|
||||
this.bind('error invalid', function (m, d) {
|
||||
this.set({
|
||||
state: 'error',
|
||||
error_code: (d && d.error_code) || '',
|
||||
get_error_text: {
|
||||
title: _t('data.upload-model.invalid-import'),
|
||||
what_about: (d && d.msg) || ''
|
||||
}
|
||||
});
|
||||
}, this);
|
||||
},
|
||||
|
||||
validate: function (attrs) {
|
||||
if (!attrs) return;
|
||||
|
||||
if (attrs.type === 'file') {
|
||||
// Number of files
|
||||
if (attrs.value && attrs.value.length) {
|
||||
return {
|
||||
msg: _t('data.upload-model.one-file')
|
||||
};
|
||||
}
|
||||
|
||||
// File name
|
||||
var name = attrs.value.name;
|
||||
if (!name) {
|
||||
return {
|
||||
msg: _t('data.upload-model.file-defined')
|
||||
};
|
||||
}
|
||||
|
||||
// File extension
|
||||
var ext = name.substr(name.lastIndexOf('.') + 1);
|
||||
if (ext) {
|
||||
ext = ext.toLowerCase();
|
||||
}
|
||||
if (!_.contains(UploadConfig.fileExtensions, ext)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.file-extension')
|
||||
};
|
||||
}
|
||||
// File size
|
||||
if ((this._userModel.get('remaining_byte_quota') * UploadConfig.fileTimesBigger) < attrs.value.size) {
|
||||
return {
|
||||
msg: _t('data.upload-model.file-size'),
|
||||
error_code: 8001
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.type === 'remote') {
|
||||
// Valid remote visualization id?
|
||||
if (!attrs.remote_visualization_id) {
|
||||
return {
|
||||
msg: _t('data.upload-model.visualization-id')
|
||||
};
|
||||
}
|
||||
// Remote size?
|
||||
if (attrs.size && ((this._userModel.get('remaining_byte_quota') * UploadConfig.fileTimesBigger) < attrs.size)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.remote-file-size'),
|
||||
error_code: 8001
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.type === 'url') {
|
||||
// Valid URL?
|
||||
if (!Utils.isURL(attrs.value)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.url-invalid')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.type === 'sql') {
|
||||
if (!attrs.value) {
|
||||
return {
|
||||
msg: _t('data.upload-model.query-undefined')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.type === 'duplication') {
|
||||
if (!attrs.value) {
|
||||
return {
|
||||
msg: _t('data.upload-model.dataset-copy-undefined')
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (attrs.type === 'service' && attrs.service_name === 'twitter_search') {
|
||||
var service_item_id = attrs.service_item_id;
|
||||
|
||||
// Empty?
|
||||
if (!service_item_id || _.isEmpty(service_item_id)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.twitter-data')
|
||||
};
|
||||
}
|
||||
|
||||
// Categories?
|
||||
if (_.isEmpty(service_item_id.categories)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.twitter-categories-invalid')
|
||||
};
|
||||
}
|
||||
|
||||
// Dates?
|
||||
var dates = service_item_id.dates;
|
||||
if (!dates || _.isEmpty(dates)) {
|
||||
return {
|
||||
msg: _t('data.upload-model.twitter-dates-empty')
|
||||
};
|
||||
}
|
||||
var isToDateValid = moment(dates.fromDate) <= moment(new Date());
|
||||
if (!dates.fromDate || !dates.toDate || !isToDateValid) {
|
||||
return {
|
||||
msg: _t('data.upload-model.twitter-dates-invalid')
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
isValid: function () {
|
||||
return this.get('value') && this.get('state') !== 'error';
|
||||
},
|
||||
|
||||
upload: function () {
|
||||
if (this.get('type') === 'file') {
|
||||
var self = this;
|
||||
this.xhr = this.save(
|
||||
{
|
||||
filename: this.get('value')
|
||||
},
|
||||
{
|
||||
success: function (m) {
|
||||
m.set('state', 'uploaded');
|
||||
},
|
||||
error: function (m, msg) {
|
||||
var message = _t('data.upload-model.connection-error');
|
||||
|
||||
if (msg && msg.status === 429) {
|
||||
var response = JSON.parse(msg.responseText);
|
||||
message = response.errors.imports;
|
||||
}
|
||||
|
||||
self.set({
|
||||
state: 'error',
|
||||
get_error_text: {
|
||||
title: _t('data.upload-model.error-happened'),
|
||||
what_about: message
|
||||
}
|
||||
});
|
||||
},
|
||||
complete: function () {
|
||||
delete self.xhr;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
stopUpload: function () {
|
||||
if (this.xhr) this.xhr.abort();
|
||||
},
|
||||
|
||||
setGuessing: function (val) {
|
||||
this.set({
|
||||
type_guessing: val,
|
||||
content_guessing: val
|
||||
});
|
||||
},
|
||||
|
||||
setPrivacy: function (val) {
|
||||
this.set('privacy', val);
|
||||
}
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user