[ADD] base import logic: implement creating an import, uploading a file and displaying the preview

bzr revid: xmo@openerp.com-20120814121610-j2rpg7u5zh4h93j1
This commit is contained in:
Xavier Morel 2012-08-14 14:16:10 +02:00
parent 84ea769476
commit b8f93a7bc6
5 changed files with 134 additions and 0 deletions

View File

@ -1,2 +1,3 @@
import controllers
import models
import tests.models

View File

@ -27,4 +27,6 @@ Re-implement openerp's file import system:
'depends': ['base'],
'installable': True,
'auto_install': False, # set to true and allow uninstall?
'js': ['static/src/js/import.js'],
'qweb': ['static/src/xml/import.xml'],
}

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
import base64
import simplejson
try:
import openerp.addons.web.common.http as openerpweb
except ImportError:
import web.common.http as openerpweb
class ImportController(openerpweb.Controller):
_cp_path = '/base_import'
@openerpweb.httprequest
def set_file(self, req, file, import_id, jsonp='callback'):
import_id = int(import_id)
written = req.session.model('base_import.import').write(import_id, {
'file': base64.b64encode(file.read()),
'file_name': file.filename,
'file_type': file.content_type,
}, req.session.eval_context(req.context))
return 'window.top.%s(%s)' % (
jsonp, simplejson.dumps({'result': written}))

View File

@ -0,0 +1,82 @@
openerp.base_import = function (instance) {
var QWeb = instance.web.qweb;
var _lt = instance.web._lt;
/**
* Safari does not deal well at all with raw JSON data being
* returned. As a result, we're going to cheat by using a
* pseudo-jsonp: instead of getting JSON data in the iframe, we're
* getting a ``script`` tag which consists of a function call and
* the returned data (the json dump).
*
* The function is an auto-generated name bound to ``window``,
* which calls back into the callback provided here.
*
* @param {Object} form the form element (DOM or jQuery) to use in the call
* @param {Object} attributes jquery.form attributes object
* @param {Function} callback function to call with the returned data
*/
function jsonp(form, attributes, callback) {
attributes = attributes || {};
var options = {jsonp: _.uniqueId('import_callback_')};
window[options.jsonp] = function () {
delete window[options.jsonp];
callback.apply(null, arguments);
};
if ('data' in attributes) {
_.extend(attributes.data, options);
} else {
_.extend(attributes, {data: options});
}
_.extend(attributes, {
dataType: 'script',
});
$(form).ajaxSubmit(attributes);
}
instance.web.DataImport = instance.web.Dialog.extend({
template: 'ImportView',
dialog_title: _lt("Import Data"),
events: {
'change input.oe_import_file': 'file_update'
},
init: function (parent, dataset) {
this._super(parent, {});
this.res_model = parent.model;
// import object id
this.id = null;
this.Import = new instance.web.Model('base_import.import');
},
start: function () {
var self = this;
return this.Import.call('create', [{
'res_model': this.res_model
}]).then(function (id) {
self.id = id;
self.$('input[name=import_id]').val(id);
});
},
//- File change section
file_update: function (e) {
if (!this.$('input.oe_import_file').val()) { return; }
// TODO: hide preview before calling set_file
jsonp(this.$element, {
url: '/base_import/set_file'
}, this.proxy('file_updated'));
},
file_updated: function () {
// immediately trigger preview...
// TODO: test that write // succeeded?
this.Import.call('parse_preview', [this.id, {
quote: '"',
separator: ',',
headers: true,
}]).then(this.proxy('preview'));
},
preview: function (result) {
this.$('table').html(QWeb.render('ImportView.preview', result));
},
});
};

View File

@ -0,0 +1,25 @@
<templates>
<t t-name="ImportView">
<form action="" method="post" enctype="multipart/form-data">
<input type="hidden" name="session_id"
t-att-value="widget.session.session_id"/>
<input type="hidden" name="import_id"/>
<label for="csvfile">CSV File:</label>
<input type="file" id="csvfile" name="file" class="oe_import_file"/>
<table class="oe_import_grid" width="100%">
</table>
</form>
</t>
<!-- TODO: column matcher? -->
<t t-name="ImportView.preview">
<tr t-if="headers" class="oe_import_grid-header">
<td t-foreach="headers" t-as="header" class="oe_import_grid-cell"
><t t-esc="header"/></td>
</tr>
<tr t-foreach="preview" t-as="row" class="oe_import_grid-row">
<td t-foreach="row" t-as="cell" class="oe_import_grid-cell"
><t t-esc="cell"/></td>
</tr>
</t>
</templates>