Merge branch 'flectra-app-store' into 'master'
[IMP] improvement on app store. See merge request flectra-hq/flectra!162
This commit is contained in:
commit
c3cd4c4867
@ -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/<int:id>'], 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/<string:id>'], 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/<int:id>'], 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)
|
||||
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
|
||||
|
||||
|
||||
|
@ -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
|
||||
});
|
||||
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: $("<h4>" + (data.error || data.success) + "</h4>"),
|
||||
title: _t(data.error ? "Error" : "Message"),
|
||||
$content: $("<h4>" + data.error + "</h4>"),
|
||||
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('<h3>No such module(s) found.</h3>');
|
||||
}
|
||||
}
|
||||
} 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('<h3>No such module(s) found.</h3>');
|
||||
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('<h3>No such module(s) found.</h3>');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.$el.html(QWeb.render('AppStore.TryError', {}));
|
||||
|
@ -32,12 +32,15 @@
|
||||
}
|
||||
li {
|
||||
float: none;
|
||||
> a:hover, > a:focus {
|
||||
> 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) {
|
||||
border-top: none;
|
||||
}
|
||||
@ -70,13 +73,13 @@
|
||||
visibility: visible;
|
||||
}
|
||||
.oe_module_desc {
|
||||
min-height: 130px;
|
||||
.oe_module_action {
|
||||
.o_module_tech_name {
|
||||
display: inline-block;
|
||||
width: 140px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden !important;
|
||||
text-overflow: ellipsis;
|
||||
.o_module_tech_name {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1495,7 +1495,7 @@
|
||||
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
|
||||
<t t-set="is_install" t-value="installed_modules.includes(m.technical_name)"/>
|
||||
<li><a t-if="is_install and mode == 'install'" app-action="uninstall" t-att-data-module-id="m.id" href="#" class=" oe_kanban_action oe_kanban_action_a">Uninstall</a></li>
|
||||
<li><a app-action="download" t-att-data-module-id="m.id" t-att-href="m.price ? 'javascript:void(0);' : '/web/module_download/' + m.id" class=" oe_kanban_action oe_kanban_action_a">Download</a></li>
|
||||
<li><a app-action="download" t-att-data-module-id="m.id" t-att-href="m.price ? 'javascript:void(0);' : '/web/module_download/' + m.md5_val" class=" oe_kanban_action oe_kanban_action_a">Download</a></li>
|
||||
<li><a app-action="view-info" t-att-data-module-id="m.id" href="#" class="oe_kanban_action oe_kanban_action_a">View Info</a></li>
|
||||
<li><a t-attf-href="{{ store_url }}/apps/{{ m.version }}/{{ m.technical_name }}" target="_blank" class=" oe_kanban_action oe_kanban_action_a">View More on Store</a></li>
|
||||
</ul>
|
||||
@ -1507,9 +1507,13 @@
|
||||
<span><t t-esc="m.description or ''"/></span>
|
||||
</p>
|
||||
<div class="oe_module_action">
|
||||
<span class="pull-left"><t t-esc="m.price ? m.price + ' ' + m.currency[1] : 'Free'"/></span><br/>
|
||||
<code class="pull-left o_module_tech_name"><small><span><t t-esc="m.technical_name"/></span></small></code>
|
||||
<div class="text-right">
|
||||
<span t-if="m.price">
|
||||
<t t-esc="m.currency[2] == 'after' ? m.price + ' ' + m.currency[1] : m.currency[1] + ' ' + m.price"/>
|
||||
</span>
|
||||
<span t-else="m.price">Free</span>
|
||||
<br/>
|
||||
<code class="o_module_tech_name" t-att-title="m.technical_name"><small><span><t t-esc="m.technical_name"/></span></small></code>
|
||||
<div class="text-right mt8">
|
||||
<t t-if="is_install">
|
||||
<span>Installed</span>
|
||||
</t>
|
||||
@ -1521,7 +1525,7 @@
|
||||
</t>
|
||||
<t t-else="">
|
||||
<button t-if="mode == 'install'" app-action="install" t-att-data-module-id="m.id" class="btn btn-primary btn-sm oe_kanban_action oe_kanban_action_button">Install</button>
|
||||
<a t-if="mode == 'download'" app-action="download" t-att-href="m.price ? 'javascript:void(0);' : '/web/module_download/' + m.id " t-att-data-module-id="m.id" class="btn btn-primary btn-sm oe_kanban_action oe_kanban_action_button">
|
||||
<a t-if="mode == 'download'" app-action="download" t-att-href="m.price ? 'javascript:void(0);' : '/web/module_download/' + m.md5_val " t-att-data-module-id="m.id" class="btn btn-primary btn-sm oe_kanban_action oe_kanban_action_button">
|
||||
<span><i class="fa fa-download"/></span>
|
||||
</a>
|
||||
</t>
|
||||
@ -1607,7 +1611,11 @@
|
||||
<span><t t-esc="m.description or ''"/></span>
|
||||
</p>
|
||||
<div class="oe_module_action">
|
||||
<span><t t-esc="m.price ? m.price + ' ' + m.currency[1] : 'Free'"/></span><br/>
|
||||
<span t-if="m.price">
|
||||
<t t-esc="m.currency[2] == 'after' ? m.price + ' ' + m.currency[1] : m.currency[1] + ' ' + m.price"/>
|
||||
</span>
|
||||
<span t-else="m.price">Free</span>
|
||||
<br/>
|
||||
<code><small><span><t t-esc="m.technical_name"/></span></small></code>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -636,9 +636,11 @@ 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)):
|
||||
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(self.get('db_name')).cursor()) as cr:
|
||||
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()
|
||||
@ -648,6 +650,9 @@ class configmanager(object):
|
||||
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):
|
||||
|
Loading…
Reference in New Issue
Block a user