diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 2e01d66e..642bcc82 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. import tarfile +import uuid import babel.messages.pofile import base64 @@ -570,7 +571,7 @@ class Home(http.Controller): @http.route(['/web/app_action'], type='json', auth="user") def app_action(self, action='', module_name='', **kwargs): - if request.env.user.has_group('base.group_system'): + if request.env.user.has_group('base.group_system') and config.get('app_store') == 'install': if module_name and action: module = request.env['ir.module.module'].search([('state', '=', 'installed'), ('name', '=', module_name)], limit=1) if module: @@ -581,7 +582,7 @@ class Home(http.Controller): @http.route(['/web/get_modules'], type='json', auth="user") def get_modules(self, **kwargs): - if request.env.user.has_group('base.group_system'): + if request.env.user.has_group('base.group_system') and config.get('app_store') in ['install', 'download']: try: modules = request.env['ir.module.module'].search_read([('state', '=', 'installed')], fields=['name']) p = requests.post(server_url + '/flectrahq/get_modules', data=kwargs) @@ -595,11 +596,11 @@ class Home(http.Controller): return False return False - @http.route(['/web/module_download/'], type='http', auth="user", methods=['GET', 'POST']) - def app_download(self, id=None): - if request.env.user.has_group('base.group_system'): + @http.route(['/web/module_download/'], type='http', auth="user", methods=['GET', 'POST']) + def app_download(self, id=None, **kwargs): + if request.env.user.has_group('base.group_system') and config.get('app_store') in ['install', 'download']: dbuuid = request.env['ir.config_parameter'].get_param('database.uuid') - p = requests.get(server_url + '/flectrahq/get_module_zip/' + str(id) + '/1', params={'dbuuid': dbuuid}) + p = requests.get(server_url + '/flectrahq/get_module_zip/' + str(id), params={'dbuuid': dbuuid}) try: data = json.loads(p.content.decode('utf-8')) if data.get('error', False): @@ -618,17 +619,12 @@ class Home(http.Controller): return request.not_found() return request.not_found() - @http.route(['/web/app_download_install/'], type='json', auth="user") - def app_download_install(self, id=None): - if request.env.user.has_group('base.group_system'): + @http.route(['/web/app_download_install'], type='json', auth="user") + def app_download_install(self, checksum=None, module_name=None, id=None, **kwargs): + if request.env.user.has_group('base.group_system') and config.get('app_store') == 'install': IrModule = request.env['ir.module.module'] try: - res_get_details = requests.get(server_url + '/flectrahq/get_module_zip/' + str(id) + '/0') - module_file_details = json.loads(res_get_details.content.decode('utf-8')) - except: - return {"error": "Internal Server Error"} - finally: - res_download = requests.get(server_url + '/flectrahq/get_module_zip/' + str(id) + '/1') + res_download = requests.get(server_url + '/flectrahq/get_module_zip/' + str(id)) downloaded_file_checksum = hashlib.sha1(res_download.content or b'').hexdigest() if res_download.status_code == 200: try: @@ -637,9 +633,8 @@ class Home(http.Controller): return data except: pass - - if module_file_details['checksum'] == downloaded_file_checksum: - path = os.path.join(tmp_dir_path, module_file_details['name']) + if checksum == downloaded_file_checksum: + path = os.path.join(tmp_dir_path, uuid.uuid4().hex) try: with open(path, 'wb') as f: f.write(res_download.content) @@ -650,14 +645,15 @@ class Home(http.Controller): finally: IrModule.update_list() root.load_addons() - modules = IrModule.search([('name', '=', module_file_details['module_name'])], limit=1) - modules.button_immediate_install() + if module_name: + modules = IrModule.search([('name', '=', module_name)], limit=1) + modules.button_immediate_install() os.remove(path) return {"success": "Module is successfully installed."} else: - return {"error": "File Crash."} - - return {"error": "Internal Server Error."} + return {"error": "File crashed when downloading."} + except: + return {"error": "Internal Server Error"} return False diff --git a/addons/web/static/src/js/apps.js b/addons/web/static/src/js/apps.js index d7595cad..f467fcd7 100644 --- a/addons/web/static/src/js/apps.js +++ b/addons/web/static/src/js/apps.js @@ -99,27 +99,20 @@ var Apps = Widget.extend({ }, _openDialogAfterAction: function (data) { if (!_.isEmpty(data)) { - var buttons = []; if (data.success) { - buttons.push({ - text: _t("Refresh"), - classes: 'btn-success', - click: function (e) { - window.location.reload(); - }, - close: true - }); + window.location.reload(); + return; } - buttons.push({ - text: _t("Cancel"), - classes: 'btn-warning', + var buttons = [{ + text: _t("OK"), + classes: 'btn-success', close: true, - }); + }]; var dialog = new Dialog(this, { size: 'medium', buttons: buttons, - $content: $("

" + (data.error || data.success) + "

"), - title: _t(data.error ? "Error" : "Message"), + $content: $("

" + data.error + "

"), + title: _t("Error"), }); dialog.open(); } @@ -152,8 +145,14 @@ var Apps = Widget.extend({ e.preventDefault(); var self = this; var id = $(e.target).data("module-id"); + var data = _.findWhere(this.all_app, {id: id}); self._rpc({ - route: '/web/app_download_install/' + id, + route: '/web/app_download_install', + params: { + id: data['md5_val'], + checksum: data['checksum'], + module_name: data['technical_name'] + } }).then(function (data) { self._openDialogAfterAction(data); }); @@ -172,10 +171,11 @@ var Apps = Widget.extend({ params: { offset: this.context.categ[this.active_categ]['offset'], categ: this.active_categ, - search: this.context.categ[self.active_categ]['search'] + search: this.context.categ[this.active_categ]['search'] } }).done(function (data) { if (data) { + self.all_app = self.all_app.concat(data.modules[self.active_categ]); self.$el.find('#' + self.active_categ + " .module-kanban:last") .after(QWeb.render('AppStore.ModuleBoxContainer', { modules: data.modules[self.active_categ], @@ -183,10 +183,15 @@ var Apps = Widget.extend({ mode: self.mode, store_url: data.store_url })); - if (!_.isEmpty(data.modules[self.active_categ])) { + if (!_.isEmpty(data.modules[self.active_categ]) && data.modules[self.active_categ].length == data.limit) { self.$el.find('#' + self.active_categ + " .load-more").show(); } else { - self.$el.find('#' + self.active_categ + " .load-more").hide(); + var $rec = self.$el.find('#' + self.active_categ + " .module-kanban "); + var $load_more = self.$el.find('#' + self.active_categ + " .load-more"); + $load_more.hide().next('h3').remove(); + if (!$rec.length) { + $load_more.after('

No such module(s) found.

'); + } } } else { self.$el.html(QWeb.render('AppStore.TryError', {})); @@ -227,18 +232,25 @@ var Apps = Widget.extend({ } }).done(function (data) { if (data) { + self.all_app = self.all_app.concat(data.modules[self.active_categ]); self.$el.find('#' + self.active_categ).find('.module-kanban').remove(); self.context.categ[self.active_categ]['search'] = search; + self.context.categ[self.active_categ]['offset'] = 0; $(QWeb.render('AppStore.ModuleBoxContainer', { modules: data.modules[self.active_categ], installed_modules: data.installed_modules, mode: self.mode, store_url: data.store_url })).prependTo(self.$el.find('#' + self.active_categ + " .o_kanban_view")); - if (!_.isEmpty(data.modules[self.active_categ])) { + if (!_.isEmpty(data.modules[self.active_categ]) && data.modules[self.active_categ].length == data.limit) { self.$el.find('#' + self.active_categ + " .load-more").show().next('h3').remove(); } else { - self.$el.find('#' + self.active_categ + " .load-more").hide().after('

No such module(s) found.

'); + var $rec = self.$el.find('#' + self.active_categ + " .module-kanban "); + var $load_more = self.$el.find('#' + self.active_categ + " .load-more"); + $load_more.hide().next('h3').remove(); + if (!$rec.length) { + $load_more.after('

No such module(s) found.

'); + } } } else { self.$el.html(QWeb.render('AppStore.TryError', {})); diff --git a/addons/web/static/src/less/apps.less b/addons/web/static/src/less/apps.less index e9b75e6c..d467431b 100644 --- a/addons/web/static/src/less/apps.less +++ b/addons/web/static/src/less/apps.less @@ -32,10 +32,13 @@ } li { float: none; - > a:hover, > a:focus { - border-color: transparent; - border-radius: 0; - background-color: mix(@brand-primary, #ffffff, 50%); + > a { + white-space: nowrap; + &:hover, &:focus { + border-color: transparent; + border-radius: 0; + background-color: mix(@brand-primary, #ffffff, 50%); + } } } @media (max-width: @screen-sm-max) { @@ -70,13 +73,13 @@ visibility: visible; } .oe_module_desc { + min-height: 130px; .oe_module_action { + white-space: nowrap; + overflow: hidden !important; + text-overflow: ellipsis; .o_module_tech_name { display: inline-block; - width: 140px; - white-space: nowrap; - overflow: hidden !important; - text-overflow: ellipsis; } } } diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index b098ba7a..56c39c87 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -1495,7 +1495,7 @@ @@ -1507,9 +1507,13 @@

-
- -
+ + + + Free +
+ +
Installed @@ -1521,7 +1525,7 @@ - + @@ -1607,7 +1611,11 @@

-
+ + + + Free +
diff --git a/flectra/tools/config.py b/flectra/tools/config.py index c1957ed7..32c2b557 100644 --- a/flectra/tools/config.py +++ b/flectra/tools/config.py @@ -636,18 +636,23 @@ class configmanager(object): except OSError: logging.getLogger(__name__).debug('Failed to create addons data dir %s', d) try: - if self.get('db_name') and not os.listdir(os.path.join(d)): - from flectra.sql_db import db_connect - with closing(db_connect(self.get('db_name')).cursor()) as cr: - if flectra.tools.table_exists(cr, 'ir_module_module'): - cr.execute("SELECT latest_version FROM ir_module_module WHERE name=%s", ('base',)) - base_version = cr.fetchone() - if base_version and base_version[0]: - tmp = base_version[0].split('.')[:2] - last_version = '.'.join(str(v) for v in tmp) - s = os.path.join(add_dir, last_version) - if float(last_version) < float(release.series) and os.listdir(os.path.join(s)): - self.copytree(s, d) + try: + from flectra.http import request, root + if request.session.db and not os.listdir(os.path.join(d)): + from flectra.sql_db import db_connect + with closing(db_connect(request.session.db).cursor()) as cr: + if flectra.tools.table_exists(cr, 'ir_module_module'): + cr.execute("SELECT latest_version FROM ir_module_module WHERE name=%s", ('base',)) + base_version = cr.fetchone() + if base_version and base_version[0]: + tmp = base_version[0].split('.')[:2] + last_version = '.'.join(str(v) for v in tmp) + s = os.path.join(add_dir, last_version) + if float(last_version) < float(release.series) and os.listdir(os.path.join(s)): + self.copytree(s, d) + root.load_addons() + except: + pass if self.get('app_store') == 'install': if not os.access(d, os.W_OK):