[IMP] web: web 1.0 database manager

Implement the database manager with plain HTML forms and HTTP controllers.
This commit is contained in:
Antony Lesuisse
2015-08-01 18:04:14 +02:00
parent 4b330f3173
commit 3cba55d7a7
8 changed files with 363 additions and 801 deletions
+62 -88
View File
@@ -37,7 +37,6 @@ from openerp.tools import topological_sort
from openerp.tools.translate import _
from openerp.tools import ustr
from openerp import http
from openerp.http import request, serialize_exception as _serialize_exception
from openerp.exceptions import AccessError
@@ -679,118 +678,93 @@ class Proxy(http.Controller):
class Database(http.Controller):
@http.route('/web/database/selector', type='http', auth="none")
def selector(self, **kw):
def _render_template(self, **d):
d.setdefault('manage',True)
d['insecure'] = openerp.tools.config['admin_passwd'] == 'admin'
d['list_db'] = openerp.tools.config['list_db']
d['langs'] = openerp.service.db.exp_list_lang()
# databases list
d['databases'] = []
try:
dbs = http.db_list()
if not dbs:
return http.local_redirect('/web/database/manager')
except openerp.exceptions.AccessDenied:
dbs = False
return env.get_template("database_selector.html").render({
'databases': dbs,
'debug': request.debug,
'error': kw.get('error')
})
@http.route('/web/database/manager', type='http', auth="none")
def manager(self, **kw):
# TODO: migrate the webclient's database manager to server side views
request.session.logout()
return env.get_template("database_manager.html").render({
'modules': simplejson.dumps(module_boot()),
})
@http.route('/web/database/get_list', type='json', auth="none")
def get_list(self):
# TODO change js to avoid calling this method if in monodb mode
try:
return http.db_list()
d['databases'] = http.db_list()
except openerp.exceptions.AccessDenied:
monodb = db_monodb()
if monodb:
return [monodb]
raise
d['databases'] = [monodb]
return env.get_template("database_manager.html").render(d)
@http.route('/web/database/create', type='json', auth="none")
def create(self, fields):
params = dict(map(operator.itemgetter('name', 'value'), fields))
db_created = request.session.proxy("db").create_database(
params['super_admin_pwd'],
params['db_name'],
bool(params.get('demo_data')),
params['db_lang'],
params['create_admin_pwd'])
if db_created:
request.session.authenticate(params['db_name'], 'admin', params['create_admin_pwd'])
return db_created
@http.route('/web/database/selector', type='http', auth="none")
def selector(self, **kw):
return self._render_template(manage=False)
@http.route('/web/database/duplicate', type='json', auth="none")
def duplicate(self, fields):
params = dict(map(operator.itemgetter('name', 'value'), fields))
duplicate_attrs = (
params['super_admin_pwd'],
params['db_original_name'],
params['db_name'],
)
return request.session.proxy("db").duplicate_database(*duplicate_attrs)
@http.route('/web/database/drop', type='json', auth="none")
def drop(self, fields):
password, db = operator.itemgetter(
'drop_pwd', 'drop_db')(
dict(map(operator.itemgetter('name', 'value'), fields)))
@http.route('/web/database/manager', type='http', auth="none")
def manager(self, **kw):
return self._render_template()
@http.route('/web/database/create', type='http', auth="none")
def create(self, master_pwd, name, lang, password, **post):
try:
if request.session.proxy("db").drop(password, db):
return True
else:
return False
except openerp.exceptions.AccessDenied:
return {'error': 'AccessDenied', 'title': 'Drop Database'}
except Exception:
return {'error': _('Could not drop database !'), 'title': _('Drop Database')}
request.session.proxy("db").create_database(master_pwd, name, bool(post.get('demo')), lang, password)
request.session.authenticate(name, login, password)
return http.local_redirect('/web/')
except Exception, e:
error = "Database creation error: %s" % e
return self._render_template(error=error)
@http.route('/web/database/duplicate', type='http', auth="none")
def duplicate(self, master_pwd, name, new_name):
try:
request.session.proxy("db").duplicate_database(master_pwd, name, new_name)
return http.local_redirect('/web/database/manager')
except Exception, e:
error = "Database duplication error: %s" % e
return self._render_template(error=error)
@http.route('/web/database/drop', type='http', auth="none")
def drop(self, master_pwd, name):
try:
request.session.proxy("db").drop(master_pwd, name)
return http.local_redirect('/web/database/manager')
except Exception, e:
error = "Database deletion error: %s" % e
return self._render_template(error=error)
@http.route('/web/database/backup', type='http', auth="none")
def backup(self, backup_db, backup_pwd, token, backup_format='zip'):
def backup(self, master_pwd, name, backup_format = 'zip'):
try:
openerp.service.security.check_super(backup_pwd)
openerp.service.db.check_super(master_pwd)
ts = datetime.datetime.utcnow().strftime("%Y-%m-%d_%H-%M-%S")
filename = "%s_%s.%s" % (backup_db, ts, backup_format)
filename = "%s_%s.%s" % (name, ts, backup_format)
headers = [
('Content-Type', 'application/octet-stream; charset=binary'),
('Content-Disposition', content_disposition(filename)),
]
dump_stream = openerp.service.db.dump_db(backup_db, None, backup_format)
dump_stream = openerp.service.db.dump_db(name, None, backup_format)
response = werkzeug.wrappers.Response(dump_stream, headers=headers, direct_passthrough=True)
response.set_cookie('fileToken', token)
return response
except Exception, e:
_logger.exception('Database.backup')
return simplejson.dumps([[],[{'error': openerp.tools.ustr(e), 'title': _('Backup Database')}]])
error = "Database backup error: %s" % e
return self._render_template(error=error)
@http.route('/web/database/restore', type='http', auth="none")
def restore(self, db_file, restore_pwd, new_db, mode):
def restore(self, master_pwd, backup_file, name, copy=False):
try:
copy = mode == 'copy'
data = base64.b64encode(db_file.read())
request.session.proxy("db").restore(restore_pwd, new_db, data, copy)
return ''
except openerp.exceptions.AccessDenied, e:
raise Exception("AccessDenied")
data = base64.b64encode(backup_file.read())
request.session.proxy("db").restore(master_pwd, name, data, copy)
return http.local_redirect('/web/database/manager')
except Exception, e:
error = "Database restore error: %s" % e
return self._render_template(error=error)
@http.route('/web/database/change_password', type='json', auth="none")
def change_password(self, fields):
old_password, new_password = operator.itemgetter(
'old_pwd', 'new_pwd')(
dict(map(operator.itemgetter('name', 'value'), fields)))
@http.route('/web/database/change_password', type='http', auth="none")
def change_password(self, master_pwd, master_pwd_new):
try:
return request.session.proxy("db").change_admin_password(old_password, new_password)
except openerp.exceptions.AccessDenied:
return {'error': 'AccessDenied', 'title': _('Change Password')}
except Exception:
return {'error': _('Error, password not changed !'), 'title': _('Change Password')}
request.session.proxy("db").change_admin_password(master_pwd, master_pwd_new)
return http.local_redirect('/web/database/manager')
except Exception, e:
error = "Master password update error: %s" % e
return self._render_template(error=error)
class Session(http.Controller):
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@@ -1,215 +0,0 @@
odoo.define('web.DatabaseManager', function (require) {
"use strict";
var core = require('web.core');
var Dialog = require('web.Dialog');
var framework = require('web.framework');
var Widget = require('web.Widget');
var _t = core._t;
var QWeb = core.qweb;
var DataBaseManager = Widget.extend({
init: function(parent) {
this._super(parent);
$.validator.addMethod('matches', function (s, _, re) {
return new RegExp(re).test(s);
}, _t("Invalid database name"));
},
start: function() {
var self = this;
$('.oe_secondary_menus_container,.oe_user_menu_placeholder').empty();
var fetch_db = this.rpc("/web/database/get_list", {}).then(
function(result) {
self.db_list = result;
},
function (_, ev) {
ev.preventDefault();
self.db_list = null;
});
var fetch_langs = this.rpc("/web/session/get_lang_list", {}).done(function(result) {
self.lang_list = result;
});
return $.when(fetch_db, fetch_langs).always(self.do_render);
},
do_render: function() {
var self = this;
core.bus.trigger('web_client_toggle_bars', true);
self.$el.html(QWeb.render("DatabaseManager", { widget : self }));
$('.oe_user_menu_placeholder').append(QWeb.render("DatabaseManager.user_menu",{ widget : self }));
$('.oe_secondary_menus_container').append(QWeb.render("DatabaseManager.menu",{ widget : self }));
$('ul.oe_secondary_submenu > li:first').addClass('active');
$('ul.oe_secondary_submenu > li').bind('click', function (event) {
var menuitem = $(this);
menuitem.addClass('active').siblings().removeClass('active');
var form_id =menuitem.find('a').attr('href');
$(form_id).show().siblings().hide();
event.preventDefault();
});
$('#back-to-login').click(self.do_exit);
self.$el.find("td").addClass("oe_form_group_cell");
self.$el.find("tr td:first-child").addClass("oe_form_group_cell_label");
self.$el.find("label").addClass("oe_form_label");
self.$el.find("form[name=create_db_form]").validate({ submitHandler: self.do_create });
self.$el.find("form[name=duplicate_db_form]").validate({ submitHandler: self.do_duplicate });
self.$el.find("form[name=drop_db_form]").validate({ submitHandler: self.do_drop });
self.$el.find("form[name=backup_db_form]").validate({ submitHandler: self.do_backup });
self.$el.find("form[name=restore_db_form]").validate({ submitHandler: self.do_restore });
self.$el.find("form[name=change_pwd_form]").validate({
messages: {
old_pwd: _t("Please enter your previous password"),
new_pwd: _t("Please enter your new password"),
confirm_pwd: {
required: _t("Please confirm your new password"),
equalTo: _t("The confirmation does not match the password")
}
},
submitHandler: self.do_change_password
});
},
destroy: function () {
this.$el.find('#db-create, #db-drop, #db-backup, #db-restore, #db-change-password, #back-to-login').unbind('click').end().empty();
this._super();
},
/**
* Blocks UI and replaces $.unblockUI by a noop to prevent third parties
* from unblocking the UI
*/
blockUI: function () {
framework.blockUI();
$.unblockUI = function () {};
},
/**
* Reinstates $.unblockUI so third parties can play with blockUI, and
* unblocks the UI
*/
unblockUI: function () {
$.unblockUI = framework.unblockUI;
framework.unblockUI();
},
/**
* Displays an error dialog resulting from the various RPC communications
* failing over themselves
*
* @param {Object} error error description
* @param {String} error.title title of the error dialog
* @param {String} error.error message of the error dialog
*/
display_error: function (error) {
return new Dialog(this, {
size: 'medium',
title: error.title,
$content: $('<div>').html(error.error)
}).open();
},
do_create: function(form) {
var fields = $(form).serializeArray();
this.rpc("/web/database/create", {'fields': fields}).done(function(result) {
if (result) {
framework.redirect('/web');
} else {
alert("Failed to create database");
}
});
},
do_duplicate: function(form) {
var self = this;
var fields = $(form).serializeArray();
self.rpc("/web/database/duplicate", {'fields': fields}).then(function(result) {
if (result.error) {
self.display_error(result);
return;
}
self.do_notify(_t("Duplicating database"), _t("The database has been duplicated."));
self.start();
});
},
do_drop: function(form) {
var self = this;
var $form = $(form),
fields = $form.serializeArray(),
$db_list = $form.find('[name=drop_db]'),
db = $db_list.val();
if (!db || !confirm(_.str.sprintf(_t("Do you really want to delete the database: %s ?"), db))) {
return;
}
self.rpc("/web/database/drop", {'fields': fields}).done(function(result) {
if (result.error) {
self.display_error(result);
return;
}
self.do_notify(_t("Dropping database"), _.str.sprintf(_t("The database %s has been dropped"), db));
self.start();
});
},
do_backup: function(form) {
var self = this;
self.blockUI();
self.session.get_file({
form: form,
success: function () {
self.do_notify(_t("Backed"), _t("Database backed up successfully"));
},
error: function(error){
if (error && error[1]) {
self.display_error(error[1][0]);
}
},
complete: function() {
self.unblockUI();
}
});
},
do_restore: function(form) {
var self = this;
self.blockUI();
$(form).ajaxSubmit({
url: '/web/database/restore',
type: 'POST',
resetForm: true,
success: function (body) {
// If empty body, everything went fine
if (!body) { return; }
if (body.indexOf('403 Forbidden') !== -1) {
self.display_error({
title: _t("Access Denied"),
error: _t("Incorrect super-administrator password")
});
} else {
self.display_error({
title: _t("Restore Database"),
error: _t("Could not restore the database")
});
}
},
complete: function() {
self.unblockUI();
self.do_notify(_t("Restored"), _t("Database restored successfully"));
}
});
},
do_change_password: function(form) {
var self = this;
self.rpc("/web/database/change_password", {
'fields': $(form).serializeArray()
}).done(function(result) {
if (result.error) {
self.display_error(result);
return;
}
self.unblockUI();
self.do_notify(_t("Changed Password"), _t("Password has been changed successfully"));
});
},
do_exit: function () {
this.$el.remove();
framework.redirect('/web');
}
});
core.action_registry.add("database_manager", DataBaseManager);
return DataBaseManager;
});
-277
View File
@@ -54,283 +54,6 @@
</div>
</t>
<t t-name="DatabaseManager">
<div class="oe_view_manager_view_form">
<div class="oe_form">
<form id="db_create" name="create_db_form" style="display: block;">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Create a New Database</span>
</h2>
</div>
</div>
</div>
<p class="oe_grey" style="margin: 10px">
Fill in this form to create an Odoo database. You can
create databases for different companies or for different
goals (testing, production). Once the database is created,
you will be able to install your first application.
</p>
<p class="oe_grey" style="margin: 10px">
By default, the master password is 'admin'. This password
is required to create, delete, dump or restore databases.
</p>
<table class="db_option_table" style="margin: 10px">
<tr>
<td><label for="super_admin_pwd">Master password:</label></td>
<td>
<input type="password" name="super_admin_pwd" class="required" value="admin"/>
</td>
</tr>
<tr>
<td><label for="db_name">Select a database name:</label></td>
<td>
<input type="text" name="db_name" class="required" matches="^[a-zA-Z0-9][a-zA-Z0-9_-]+$" autofocus="true" placeholder="e.g. mycompany"/>
</td>
</tr>
<tr>
<td><label for="demo_data">Load demonstration data:</label></td>
<td class="oe_form_group_cell">
<span class="oe_form_field oe_form_field_boolean oe_grey" >
<input type="checkbox" name="demo_data" />
Check this box to evaluate Odoo.
</span>
</td>
</tr>
<tr>
<td><label for="db_lang">Default language:</label></td>
<td class="oe_form_field oe_form_field_selection">
<select name="db_lang" t-if="widget.lang_list" class="oe_inline">
<t t-foreach="widget.lang_list" t-as="lang">
<option t-att-value="lang[0]" t-att-selected="lang[0] === 'en_US' ? 'selected' : undefined">
<t t-esc="lang[1]" />
</option>
</t>
</select>
</td>
</tr>
<tr>
<td><label for="create_admin_pwd">Choose a password:</label></td>
<td><input type="password" name="create_admin_pwd" class="required" /></td>
</tr>
<tr>
<td><label for="create_confirm_pwd">Confirm password:</label></td>
<td><input type="password" name="create_confirm_pwd" class="required" equalTo="input[name=create_admin_pwd]"/></td>
</tr>
<tr>
<td></td>
<td><button type="submit" class="oe_button oe_highlight db_create">Create Database</button></td>
</tr>
</table>
</form>
<form id="db_duplicate" name="duplicate_db_form" style="display: none;">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Duplicate Database</span>
</h2>
<button type="submit" class="oe_button oe_highlight db_duplicate">Duplicate</button>
</div>
</div>
</div>
<table align="center" class="db_option_table">
<tr>
<td><label for="super_admin_pwd">Master password:</label></td>
<td><input type="password" name="super_admin_pwd" class="required" value="admin" /></td>
</tr>
<tr>
<td><label for="db_original_name">Original database name:</label></td>
<td><input type="text" name="db_original_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_-]+$" autofocus="true"/></td>
</tr>
<tr>
<td><label for="db_name">New database name:</label></td>
<td><input type="text" name="db_name" class="required" matches="^[a-zA-Z][a-zA-Z0-9_-]+$" /></td>
</tr>
</table>
</form>
<form id="db_drop" name="drop_db_form" style="display: none; ">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Drop Database</span>
</h2>
<button type="submit" class="oe_button oe_highlight db_drop">Drop</button>
</div>
</div>
</div>
<table align="center" class="db_option_table">
<tr>
<td><label for="drop_db">Database:</label></td>
<td class="oe_form_field oe_form_field_selection">
<select t-if="widget.db_list" name="drop_db" autofocus="autofocus">
<t t-foreach="widget.db_list" t-as="db">
<option t-att-value="db">
<t t-esc="db" />
</option>
</t>
</select>
<input t-if="!widget.db_list" name="drop_db" class="required" type="text" autofocus="autofocus"/>
</td>
</tr>
<tr>
<td><label for="drop_password">Master Password:</label></td>
<td><input type="password" name="drop_pwd" class="required" /></td>
</tr>
</table>
</form>
<form id="db_backup" name="backup_db_form" target="backup-target" action="/web/database/backup" style="display: none;">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Backup Database</span>
</h2>
<button type="submit" class="oe_button oe_highlight db_backup">Backup</button>
</div>
</div>
</div>
<input type="hidden" name="token" />
<table align="center" class="db_option_table">
<tr>
<td><label for="backup_db">Database:</label></td>
<td class="oe_form_field oe_form_field_selection ">
<select t-if="widget.db_list" name="backup_db" autofocus="autofocus">
<t t-foreach="widget.db_list" t-as="db">
<option t-att-value="db">
<t t-esc="db" />
</option>
</t>
</select>
<input t-if="!widget.db_list" name="backup_db" class="required" type="text" autofocus="autofocus"/>
</td>
</tr>
<tr>
<td><label for="backup_format">Backup format:</label></td>
<td class="oe_form_field oe_form_field_selection">
<select name="backup_format">
<option value="zip">zip (includes filestore)</option>
<option value="dump">pg_dump custom format (without filestore)</option>
</select>
</td>
</tr>
<tr>
<td><input type="password" name="backup_pwd" class="required" /></td>
</tr>
</table>
</form>
<form id="db_restore" name="restore_db_form" style="display: none; ">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Restore Database</span>
</h2>
<button type="submit" class="oe_button oe_highlight db_restore">Restore</button>
</div>
</div>
</div>
<table align="center" class="db_option_table">
<tr>
<td><label for="restore_pwd">Master Password:</label></td>
<td><input type="password" name="restore_pwd" class="required" autofocus="autofocus"/></td>
</tr>
<tr>
<td><label for="restore_db">File:</label></td>
<td><input type="file" name="db_file" class="required"/></td>
</tr>
<tr>
<td><label for="new_db">New database name:</label></td>
<td><input type="text" name="new_db" class="required"/></td>
</tr>
<tr>
<td><label for="mode">Mode:</label></td>
<td><select name="mode" class="required">
<option value="restore">Backup Restore</option>
<option value="copy">Copy of an existing database</option>
</select></td>
</tr>
</table>
</form>
<form id="db_change_password" name="change_pwd_form" style="display: none;">
<div class="oe_view_manager oe_view_manager_current">
<div class="oe-control-panel" style="padding: 8px;">
<div class="oe_header_row">
<h2 class="oe_view_title">
<span class="oe_view_title_text oe_breadcrumb_title">Change Master Password</span>
</h2>
<button type="submit" class="oe_button oe_highlight db-change-password">Change Password</button>
</div>
</div>
</div>
<table align="center" class="db_option_table">
<tr>
<td><label for="old_pwd">Master password:</label></td>
<td><input type="password" name="old_pwd" class="required" minlength="1" autofocus="autofocus"/></td>
</tr>
<tr>
<td><label for="new_pwd">New master password:</label></td>
<td><input type="password" name="new_pwd" class="required" minlength="1"/></td>
</tr>
<tr>
<td><label for="confirm_pwd">Confirm new master password:</label></td>
<td><input type="password" name="confirm_pwd" class="required" equalTo="input[name=new_pwd]" minlength="1"/> </td>
</tr>
</table>
</form>
</div>
</div>
</t>
<t t-name="DatabaseManager.user_menu">
<li>
<a id="back-to-login" href="#">Back to Login</a>
</li>
</t>
<t t-name="DatabaseManager.menu">
<div class="oe_secondary_menu_section">Database Management</div>
<ul class="oe_secondary_submenu nav nav-pills nav-stacked">
<li><a href="#db_create">Create</a></li>
<li><a href="#db_duplicate">Duplicate</a></li>
<li><a href="#db_drop">Drop</a></li>
<li><a href="#db_backup">Backup</a></li>
<li><a href="#db_restore">Restore</a></li>
<li><a href="#db_change_password">Password</a></li>
</ul>
</t>
<t t-name="ChangePassword">
<form name="change_password_form" method="POST">
<div class="oe_form">
<table align="center">
<tr>
<td class="oe_form_group_cell oe_form_group_cell_label"><label for="old_pwd" class="oe_form_label">Old Password:</label></td>
<td class="oe_form_group_cell"><input type="password" name="old_pwd"
minlength="1" autofocus="autofocus"/></td>
</tr>
<tr>
<td class="oe_form_group_cell oe_form_group_cell_label"><label for="new_password" class="oe_form_label">New Password:</label></td>
<td class="oe_form_group_cell"><input type="password" name="new_password"
minlength="1"/></td>
</tr>
<tr>
<td class="oe_form_group_cell oe_form_group_cell_label"><label for="confirm_pwd" class="oe_form_label">Confirm New Password:</label></td>
<td class="oe_form_group_cell"><input type="password" name="confirm_pwd"
minlength="1"/></td>
</tr>
<tr>
<td colspan="2" align="right">
<button class='oe_button oe_form_button'>Change Password</button>
<button type="button" class="oe_button oe_form_button_cancel oe_form_button oe_link" href="javascript:void(0)"><span>Cancel</span></button>
</td>
</tr>
</table>
</div>
</form>
</t>
<t t-name="Menu.needaction_counter">
<div id="menu_counter" class="badge pull-right">
<t t-if="widget.needaction_counter &gt; 99"> 99+ </t>
+301 -134
View File
@@ -1,144 +1,311 @@
<!DOCTYPE html>
<html style="height: 100%;">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Odoo</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon"/>
<link rel="stylesheet" href="/web/static/src/css/full.css" />
<script src="/web/static/lib/es5-shim/es5-shim.min.js" type="text/javascript"></script>
<script src="/web/static/lib/underscore/underscore.js" type="text/javascript"></script>
<script src="/web/static/lib/underscore.string/lib/underscore.string.js" type="text/javascript"></script>
<script src="/web/static/lib/spinjs/spin.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery/jquery.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery/jquery.browser.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.blockUI/jquery.blockUI.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.hotkeys/jquery.hotkeys.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.placeholder/jquery.placeholder.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.timeago/jquery.timeago.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.form/jquery.form.js" type="text/javascript"></script>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Odoo</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="/web/static/lib/fontawesome/css/font-awesome.css">
<link rel="stylesheet" href="/web/static/lib/bootstrap/css/bootstrap.css">
<script src="/web/static/lib/jquery/jquery.js" type="text/javascript"></script>
<script src="/web/static/lib/bootstrap/js/modal.js"></script>
<script src="/web/static/lib/bootstrap/js/tooltip.js"></script>
<script src="/web/static/lib/bootstrap/js/dropdown.js"></script>
<script type="text/javascript">
$(function() {
// Little eye
$('body').on('mousedown','.o_little_eye',function(ev) {
$(ev.target).siblings('input').prop('type','text');
});
$('body').on('mouseup','.o_little_eye',function(ev) {
$(ev.target).siblings('input').prop('type','password');
});
// db modal
$('body').on('click','.o_database_action', function(ev) {
ev.preventDefault();
var db = $(ev.currentTarget).data('db');
var target = $(ev.currentTarget).data('target');
$(target).find('input[name=name]').val(db);
$(target).modal();
});
});
</script>
</head>
<script src="/web/static/lib/jquery.ba-bbq/jquery.ba-bbq.js" type="text/javascript"></script>
{% macro master_input() -%}
<div class="form-group">
{% if insecure %}
<input type="hidden" name="master_pwd" class="form-control" value="admin"/>
{% else %}
<label for="master_pwd" class="control-label">Master Password</label>
<input type="password" name="master_pwd" class="form-control" required="required" autofocus="autofocus"/>
{% endif %}
</div>
{%- endmacro %}
<script src="/web/static/lib/jquery.validate/jquery.validate.js" type="text/javascript"></script>
<script src="/web/static/lib/autosize/autosize.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.scrollTo/jquery.scrollTo.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.textext/jquery.textext.js" type="text/javascript"></script>
<script src="/web/static/lib/select2/select2.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.ui/jquery-ui.js" type="text/javascript"></script>
<script src="/web/static/lib/jquery.ui.notify/js/jquery.notify.js" type="text/javascript"></script>
{% macro create_form() -%}
<p>Fill in this form to create an Odoo database. You may create
databases for different companies or for different goals (testing,
production). Once the database is created, you will be able to
install your first application.</p>
{{ master_input() }}
<div class="form-group">
<div class="row">
<div class="col-md-8">
<label for="name" class="control-label">Database Name</label>
<input type="text" name="name" class="form-control" required="required" autocomplete="off"/>
</div>
<div class="col-md-4">
<label for="name" class="control-label">Language</label>
<select name="lang" class="form-control" required="required" autocomplete="off">
{% for lang in langs %}
<option {% if lang[0] == "en_US" %}selected="selected" {% endif %}value="{{ lang[0] }}">{{ lang[1] }}</option>
{% endfor %}
</select>
</div>
</div>
</div>
<div class="form-group has-feedback">
<label for="password" class="control-label">Password of <em>admin</em> user</label>
<input type="password" name="password" class="form-control" required="required" autocomplete="off"/>
<span class="fa fa-eye o_little_eye form-control-feedback" aria-hidden="true" style="cursor: pointer; pointer-events: auto"></span>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input name="demo" type="checkbox" class="pull-right" value="1">
<span>Load demonstration data</span>
<span class="text-muted"> (Check this box to evaluate Odoo)</span>
</label>
</div>
</div>
{%- endmacro %}
<link rel="stylesheet" href='/website/static/src/less/import_bootstrap.less'/>
<link rel="stylesheet" href="/web/static/src/less/enterprise_compatibility.less"/>
<link rel="stylesheet" href="/web/static/src/less/utils.less"/>
<script src="/web/static/lib/bootstrap/js/modal.js"></script>
<script src="/web/static/lib/bootstrap/js/tooltip.js"></script>
<script src="/web/static/lib/backbone/backbone.js" type="text/javascript"></script>
<script src="/web/static/lib/qweb/qweb2.js" type="text/javascript"></script>
<script src="/web/static/lib/py.js/lib/py.js" type="text/javascript"></script>
<body class="container">
<script type="text/javascript" src="/web/static/src/js/boot.js"></script>
<script type="text/javascript">
odoo._modules = ['web', 'web_kanban'];
</script>
<script type="text/javascript" src="/web/static/src/js/framework/class.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/translation.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/ajax.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/time.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/mixins.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/widget.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/registry.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/session.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/model.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/utils.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/core.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/formats.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/view.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/pyeval.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/data.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/data_model.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/misc.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/session_instance.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/crash_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/action_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/control_panel.js"></script>
<script type="text/javascript" src="/web/static/src/js/view_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/web_client.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/data_export.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/date_picker.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/database_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/loading.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/notification.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/sidebar.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/systray_menu.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/user_menu.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/dialog.js"></script>
<script type="text/javascript" src="/web/static/src/js/menu.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/list_common.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/list_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/form_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/form_common.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/search_view.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/search_filters.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/search_inputs.js"></script>
<script type="text/javascript" src="/web/static/src/js/views/search_menus.js"></script>
<script type="text/javascript" src="/web/static/lib/moment/moment.js"></script>
<script type="text/javascript" src="/web/static/lib/bootstrap-datetimepicker/src/js/bootstrap-datetimepicker.js"></script>
<link rel="stylesheet" href="/web/static/lib/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css"/>
<link href="/web/static/lib/fontawesome/css/font-awesome.css" rel="stylesheet"/>
<link href="/web/static/lib/jquery.textext/jquery.textext.css" rel="stylesheet"/>
<link href="/web/static/lib/select2/select2.css" rel="stylesheet"/>
<link href="/web/static/lib/jquery.ui/jquery-ui.css" rel="stylesheet"/>
<link href="/web/static/lib/jquery.ui.notify/css/ui.notify.css" rel="stylesheet"/>
<link href="/web/static/lib/bootstrap/css/bootstrap.css" rel="stylesheet"/>
<link href="/web/static/src/css/base.css" rel="stylesheet"/>
<link href="/web/static/src/css/data_export.css" rel="stylesheet"/>
<link href="/base/static/src/css/modules.css" rel="stylesheet"/>
<script type="text/javascript">
$(function() {
odoo.define('web.web_client', function (require) {
var WebClient = require('web.WebClient');
var web_client = new WebClient(null, {action: 'database_manager'});
web_client.setElement($(document.body));
web_client.start();
return web_client;
});
});
</script>
</head>
<body>
<nav id="oe_main_menu_navbar" class="navbar navbar-inverse" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse" id="oe_main_menu_placeholder">
<ul class="nav navbar-nav navbar-right oe_user_menu_placeholder"></ul>
</div>
</nav>
<div class="openerp openerp_webclient_container oe_webclient">
<div class="oe_leftbar">
<a class="oe_logo">
<span class="oe_logo_edit">Edit Company data</span>
<img src='/web/binary/company_logo'/>
</a>
<div class="oe_secondary_menus_container"></div>
<div class="oe_footer">
Powered by <a href="http://www.odoo.com" target="_blank"><span>Odoo</span></a>
</div>
</div>
<div class="oe_application">
<!-- Database List -->
<div class="row">
<div class="col-md-6 col-md-offset-3 o_database_list">
<div class="text-center">
<img src="/web/static/src/img/logo2.png" class="img-responsive center-block"/>
</div>
{% if insecure and databases %}
<div class="alert alert-warning">
Warning, your Odoo database manager is not protected.
Please <a href="#" data-toggle="modal" data-target=".o_database_master">set a master password</a>
to secure it.
</div>
{% endif %}
{% if error %}
<div class="alert alert-danger">{{ error }}</div>
{% endif %}
{% if databases %}
<div class="list-group">
{% for db in databases %}
<a href="/web?db={{ db }}" class="list-group-item">
{{ db }}
{% if manage %}
<div class="text-right pull-right">
<span data-db="{{ db }}" data-target=".o_database_backup" class="o_database_action btn-link"><i class="fa fa-floppy-o fa-fw"></i> Backup</span>
<span data-db="{{ db }}" data-target=".o_database_duplicate" class="o_database_action btn-link"><i class="fa fa-files-o fa-fw"></i> Duplicate</span>
<span data-db="{{ db }}" data-target=".o_database_delete" class="o_database_action btn-link"><i class="fa fa-trash-o fa-fw"></i> Delete</span>
</div>
{% endif %}
</a>
{% endfor %}
</div>
{% if manage %}
<div class="text-left">
<button type="button" data-toggle="modal" data-target=".o_database_create" class="btn btn-sm btn-primary">
Create Database
</button>
<button type="button" data-toggle="modal" data-target=".o_database_restore" class="btn btn-sm btn-primary">
Restore Database
</button>
<button type="button" data-toggle="modal" data-target=".o_database_master" class="btn btn-sm btn-primary">
Set Master Password
</button>
</div>
{% else %}
<div class="text-center">
<a href="/web/database/manager">Manage databases</a>
</div>
{% endif %}
{% else %}
<form role="form" action="/web/database/create" method="post">
{{ create_form() }}
<input type="submit" value="Create database" class="btn btn-primary pull-left"/>
</form>
{% endif %}
</div>
</div>
<!--[if lte IE 8]>
<script src="//ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<script>CFInstall.check({mode: "overlay"});</script>
<![endif]-->
</body>
<!-- Create -->
<div class="modal fade o_database_create" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<form role="form" action="/web/database/create" method="post">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Create Database</h4>
</div>
<div class="modal-body">
{{ create_form() }}
</div>
<div class="modal-footer">
<input type="submit" value="Continue" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
<!-- Restore -->
<div class="modal fade o_database_restore" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Restore Database</h4>
</div>
<form id="form_restore_db" role="form" action="/web/database/restore" method="post" enctype="multipart/form-data">
<div class="modal-body">
{{ master_input() }}
<div class="form-group">
<label for="backup_file" class="control-label">File</label>
<input type="file" name="backup_file" class="required"/>
</div>
<div class="form-group">
<label for="name" class="control-label">Database Name</label>
<input type="text" name="name" class="form-control" required="required"/>
</div>
<div class="form-group">
<div class="checkbox">
<label>
<input name="copy" type="checkbox" class="pull-right" value="1">
<span>Generate a new database uuid.</span>
</label>
</div>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Continue" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
<!-- Master password -->
<div class="modal fade o_database_master" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Set Master Password</h4>
</div>
<form id="form_change_pwd" role="form" action="/web/database/change_password" method="post">
<div class="modal-body">
<p>The master password is required to create, delete, dump or restore databases.</p>
{{ master_input() }}
<div class="form-group has-feedback">
<label for="master_pwd_new" class="control-label">New Master Password</label>
<input type="password" name="master_pwd_new" class="form-control" required="required" autocomplete="off"/>
<span class="fa fa-eye o_little_eye form-control-feedback" aria-hidden="true" style="cursor: pointer; pointer-events: auto"></span>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Continue" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
<!-- Duplicate DB -->
<div class="modal fade o_database_duplicate" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Duplicate Database</h4>
</div>
<form id="form-duplicate-db" role="form" action="/web/database/duplicate" method="post">
<div class="modal-body">
{{ master_input() }}
<div class="form-group">
<label for="name" class="control-label">Database Name</label>
<input type="text" name="name" class="form-control" required="required" readonly="readonly"/>
</div>
<div class="form-group">
<label for="new_name" class="control-label">New Name</label>
<input type="text" name="new_name" class="form-control" required="required"/>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Continue" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
<!-- Drop DB -->
<div class="modal fade o_database_delete" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Delete Database</h4>
</div>
<form id="form_drop_db" role="form" action="/web/database/drop" method="post">
<div class="modal-body">
{{ master_input() }}
<div class="form-group">
<label for="name" class="control-label">Database</label>
<input type="text" name="name" class="form-control" required="required" readonly="readonly"/>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Delete" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
<!-- Backup DB -->
<div class="modal fade o_database_backup" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Backup Database</h4>
</div>
<form id="form_backup_db" role="form" action="/web/database/backup" method="post">
<div class="modal-body">
{{ master_input() }}
<div class="form-group">
<label for="name" class="control-label">Database Name</label>
<input type="text" name="name" class="form-control" required="required" readonly="readonly"/>
</div>
<div class="form-group">
<label for="backup_format" class="control-label">Backup Format</label>
<select name="backup_format" id="backup_format" class="form-control" required="required">
<option value="zip">zip (includes filestore)</option>
<option value="dump">pg_dump custom format (without filestore)</option>
</select>
</div>
</div>
<div class="modal-footer">
<input type="submit" value="Backup" class="btn btn-primary pull-right"/>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
-65
View File
@@ -1,65 +0,0 @@
<!DOCTYPE html>
<html style="height: 100%">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Odoo</title>
<link rel="shortcut icon" href="/web/static/src/img/favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="/web/static/src/css/full.css">
<link rel="stylesheet" href="/web/static/lib/fontawesome/css/font-awesome.css">
<link rel="stylesheet" href="/web/static/lib/bootstrap/css/bootstrap.css">
<link rel="stylesheet" href="/web/static/src/css/base.css">
<script type="text/javascript">
function dbchanged() {
document.getElementById('dbselector').submit();
}
</script>
<body class="oe_single_form">
<div class="oe_single_form_container modal-content">
<form class="oe_dbselector_form" id="dbselector" role="form" action="/web" method="get">
<div class="oe_single_form_logo">
<img src="/web/static/src/img/logo2.png"/>
</div>
<hr/>
{% if error %}
<p class="alert alert-danger">
{{ error }}
</p>
{% endif %}
<div class="form-group field-db">
<label for="db" class="control-label">Select database</label>
{% if databases %}
<select name="db" id="db" class="form-control" required="required" autofocus="autofocus" onchange="dbchanged()">
<option></option>
{% for db in databases %}
<option value="{{ db }}">{{ db }}</option>
{% endfor %}
</select>
{% else %}
<input type="text" name="db" id="db" class="form-control" required="required" autofocus="autofocus"/>
{% endif %}
</div>
{% if debug %}
<input type="hidden" name="debug" value=""/>
{% endif %}
<noscript>
<hr/>
<input type="submit" value="Continue" class="btn btn-primary pull-right"/>
</noscript>
<div class="oe_single_form_footer">
<a class="oe_login_manage_db" href="/web/database/manager{% if debug %}?debug{% endif %}">Manage Databases</a> |
<a href="http://www.openerp.com" target="_blank">Powered by <span>OpenERP</span></a>
</div>
</form>
</div>
</body>
</html>
-1
View File
@@ -121,7 +121,6 @@
<script type="text/javascript" src="/web/static/src/js/framework/session_instance.js"></script>
<script type="text/javascript" src="/web/static/src/js/framework/crash_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/change_password.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/database_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/debug_manager.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/data_export.js"></script>
<script type="text/javascript" src="/web/static/src/js/widgets/date_picker.js"></script>
-21
View File
@@ -63,25 +63,4 @@ odoo.define_section('basic section', [], function (test, mock) {
});
});
test('JSON-RPC', ['web.DatabaseManager'], function (assert, DatabaseManager) {
assert.expect(3);
var fetched_dbs = false, fetched_langs = false;
mock.add('/web/database/get_list', function () {
fetched_dbs = true;
return ['foo', 'bar', 'baz'];
});
mock.add('/web/session/get_lang_list', function () {
fetched_langs = true;
return [['vo_IS', 'Hopelandic / Vonlenska']];
});
var dbm = new DatabaseManager({});
var $fix = $( "#qunit-fixture");
return dbm.appendTo($fix).then(function () {
assert.ok(fetched_dbs, "should have fetched databases");
assert.ok(fetched_langs, "should have fetched languages");
assert.deepEqual(dbm.db_list, ['foo', 'bar', 'baz']);
});
});
});