Merge lp:~fabien-morin/unifield-web/fm-us-2925 into lp:unifield-web
- fm-us-2925
- Merge into trunk
Proposed by
jftempo
Status: | Merged |
---|---|
Merged at revision: | 4883 |
Proposed branch: | lp:~fabien-morin/unifield-web/fm-us-2925 |
Merge into: | lp:unifield-web |
Diff against target: |
615 lines (+460/-5) 6 files modified
addons/openerp/controllers/database.py (+272/-3) addons/openerp/controllers/templates/auto_create.mako (+70/-0) addons/openerp/controllers/templates/auto_create_progress.mako (+80/-0) addons/openerp/controllers/utils.py (+12/-0) addons/openerp/po/messages/fr.po (+2/-2) addons/openerp/static/css/database.css (+24/-0) |
To merge this branch: | bzr merge lp:~fabien-morin/unifield-web/fm-us-2925 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
UniField Dev Team | Pending | ||
Review via email: mp+334060@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'addons/openerp/controllers/database.py' |
2 | --- addons/openerp/controllers/database.py 2017-07-11 12:19:46 +0000 |
3 | +++ addons/openerp/controllers/database.py 2017-11-21 17:05:56 +0000 |
4 | @@ -22,10 +22,12 @@ |
5 | import re |
6 | import time |
7 | import os |
8 | +import sys |
9 | |
10 | import cherrypy |
11 | import formencode |
12 | |
13 | +from openobject import paths |
14 | from openobject.controllers import BaseController |
15 | from openobject.tools import url, expose, redirect, validate, error_handler |
16 | import openobject |
17 | @@ -35,6 +37,9 @@ |
18 | from openerp.utils import rpc, get_server_version, is_server_local, serve_file |
19 | from tempfile import NamedTemporaryFile |
20 | import shutil |
21 | +import ConfigParser |
22 | +from ConfigParser import NoOptionError, NoSectionError |
23 | +import threading |
24 | |
25 | def get_lang_list(): |
26 | langs = [('en_US', 'English (US)')] |
27 | @@ -50,6 +55,8 @@ |
28 | except: |
29 | return [] |
30 | |
31 | +class DatabaseExist(Exception): pass |
32 | + |
33 | class ReplacePasswordField(openobject.widgets.PasswordField): |
34 | params = { |
35 | 'autocomplete': 'Autocomplete field', |
36 | @@ -116,6 +123,23 @@ |
37 | validator = openobject.validators.Schema(chained_validators=[formencode.validators.FieldsMatch("admin_password","confirm_password")]) |
38 | |
39 | |
40 | +class FormAutoCreate(DBForm): |
41 | + name = "auto_create" |
42 | + string = _('Instance Auto Creation') |
43 | + action = '/openerp/database/do_auto_create' |
44 | + submit_text = _('Start auto creation') |
45 | + #form_attrs = {'onsubmit': 'return window.confirm(_("Do you really want to drop the selected database?"))'} |
46 | + fields = [ |
47 | + ReplacePasswordField(name='password', label=_('Super admin password:')), |
48 | + ] |
49 | + |
50 | + |
51 | +class AutoCreateProgress(DBForm): |
52 | + name = "get_auto_create_progress" |
53 | + string = _('Auto Creation Progress') |
54 | + action = '/openerp/database/get_auto_create_progress' |
55 | + |
56 | + |
57 | class FormDrop(DBForm): |
58 | name = "drop" |
59 | string = _('Drop database') |
60 | @@ -127,6 +151,7 @@ |
61 | ReplacePasswordField(name='password', label=_('Drop password:')), |
62 | ] |
63 | |
64 | + |
65 | class FormBackup(DBForm): |
66 | name = "backup" |
67 | string = _('Backup database') |
68 | @@ -137,10 +162,12 @@ |
69 | ReplacePasswordField(name='password', label=_('Backup password:')), |
70 | ] |
71 | |
72 | + |
73 | class FileField(openobject.widgets.FileField): |
74 | def adjust_value(self, value, **params): |
75 | return False |
76 | |
77 | + |
78 | class FormRestore(DBForm): |
79 | name = "restore" |
80 | string = _('Restore database') |
81 | @@ -169,6 +196,7 @@ |
82 | |
83 | |
84 | _FORMS = { |
85 | + 'auto_create': FormAutoCreate(), |
86 | 'create': FormCreate(), |
87 | 'drop': FormDrop(), |
88 | 'backup': FormBackup(), |
89 | @@ -176,9 +204,13 @@ |
90 | 'password': FormPassword() |
91 | } |
92 | |
93 | + |
94 | class DatabaseCreationError(Exception): pass |
95 | + |
96 | + |
97 | class DatabaseCreationCrash(DatabaseCreationError): pass |
98 | |
99 | + |
100 | class Database(BaseController): |
101 | |
102 | _cp_path = "/openerp/database" |
103 | @@ -248,7 +280,7 @@ |
104 | break |
105 | else: |
106 | time.sleep(1) |
107 | - except: |
108 | + except Exception as e: |
109 | raise DatabaseCreationCrash() |
110 | except DatabaseCreationCrash: |
111 | self.msg = {'message': (_("The server crashed during installation.\nWe suggest you to drop this database.")), |
112 | @@ -258,15 +290,252 @@ |
113 | self.msg = {'message': _('Bad super admin password'), |
114 | 'title' : e.title} |
115 | return self.create() |
116 | - except Exception: |
117 | + except Exception as e: |
118 | self.msg = {'message':_("Could not create database.")} |
119 | - |
120 | return self.create() |
121 | |
122 | if ok: |
123 | raise redirect('/openerp/menu', {'next': '/openerp/home'}) |
124 | raise redirect('/openerp/login', db=dbname) |
125 | |
126 | + @expose(template="/openerp/controllers/templates/auto_create.mako") |
127 | + def auto_create(self, tg_errors=None, **kw): |
128 | + form = _FORMS['auto_create'] |
129 | + error = self.msg |
130 | + self.msg = {} |
131 | + return dict(form=form, error=error) |
132 | + |
133 | + @expose() |
134 | + def get_auto_create_progress(self, **kw): |
135 | + config_file_name = 'uf_auto_install.conf' |
136 | + if sys.platform == 'win32': |
137 | + config_file_path = os.path.join(paths.root(), '..', 'UFautoInstall', config_file_name) |
138 | + else: |
139 | + config_file_path = os.path.join(paths.root(), '..', 'unifield-server', 'UFautoInstall', config_file_name) |
140 | + if not os.path.exists(config_file_path): |
141 | + return False |
142 | + config = ConfigParser.ConfigParser() |
143 | + config.read(config_file_path) |
144 | + dbname = config.get('instance', 'db_name') |
145 | + self.resume, self.progress, self.state, self.error, monitor_status = rpc.session.execute_db('creation_get_resume_progress', dbname) |
146 | + my_dict = { |
147 | + 'resume': self.resume, |
148 | + 'progress': self.progress, |
149 | + 'state': self.state, |
150 | + 'error': self.error, |
151 | + 'monitor_status': monitor_status, |
152 | + } |
153 | + import json |
154 | + return json.dumps(my_dict) |
155 | + |
156 | + @expose(template="/openerp/controllers/templates/auto_create_progress.mako") |
157 | + def auto_create_progress(self, tg_errors=None, **kw): |
158 | + finish = "" |
159 | + finished = "False" |
160 | + data_collected = "False" |
161 | + return dict(finish=finish, percent=self.progress, resume=self.resume, total=finished, |
162 | + data_collected=data_collected) |
163 | + |
164 | + def check_not_empty_string(self, config, section, option): |
165 | + if not config.has_option(section, option) or not config.get(section, option): |
166 | + self.msg = {'message': ustr(_('The option \'%s\' from section \'[%s]\' cannot be empty, please set a value.') % (option, section)), |
167 | + 'title': ustr(_('Empty option'))} |
168 | + |
169 | + def check_mandatory_int(self, config, section, option): |
170 | + try: |
171 | + value = config.getint(section, option) |
172 | + except ValueError: |
173 | + self.msg = {'message': ustr(_('The option \'%s\' from section \'[%s]\' have to be a int.') % (option, section)), |
174 | + 'title': ustr(_('Wrong option value'))} |
175 | + return |
176 | + if not value: |
177 | + self.msg = {'message': ustr(_('The option \'%s\' from section \'[%s]\' cannot be empty, please set a value.') % (option, section)), |
178 | + 'title': ustr(_('Empty option'))} |
179 | + |
180 | + def check_possible_value(self, config, section, option, possible_values): |
181 | + value = config.get(section, option) |
182 | + if value not in possible_values: |
183 | + self.msg = {'message': ustr(_('The option \'%s\' from section \'[%s]\' have to be one of those values: %r. (currently it is \'%s\').') % (option, section, possible_values, value)), |
184 | + 'title': ustr(_('Wrong option'))} |
185 | + |
186 | + def check_config_file(self, file_path): |
187 | + ''' |
188 | + perform some basic checks to avoid crashing later |
189 | + ''' |
190 | + if not os.path.exists(file_path): |
191 | + self.msg = {'message': ustr(_("The auto creation config file '%s' does not exists.") % file_path), |
192 | + 'title': ustr(_('Auto creation file not found'))} |
193 | + |
194 | + config = ConfigParser.ConfigParser() |
195 | + config.read(file_path) |
196 | + try: |
197 | + db_name = config.get('instance', 'db_name') |
198 | + if not re.match('^[a-zA-Z][a-zA-Z0-9_-]+$', db_name): |
199 | + self.msg = {'message': ustr(_("You must avoid all accents, space or special characters.")), |
200 | + 'title': ustr(_('Bad database name'))} |
201 | + return |
202 | + |
203 | + admin_password = config.get('instance', 'admin_password') |
204 | + res = rpc.session.execute_db('check_super_password_validity', admin_password) |
205 | + if res is not True: |
206 | + self.msg = {'message': res, |
207 | + 'title': ustr(_('Bad admin password'))} |
208 | + return |
209 | + |
210 | + # check the mandatory string fields have a value |
211 | + not_empty_string_option_list = ( |
212 | + ('instance', 'oc'), |
213 | + ('instance', 'admin_password'), |
214 | + ('instance', 'sync_user'), |
215 | + ('instance', 'sync_pwd'), |
216 | + ('instance', 'instance_level'), |
217 | + ('instance', 'parent_instance'), |
218 | + ('instance', 'lang'), |
219 | + ('backup', 'auto_bck_path'), |
220 | + ('reconfigure', 'prop_instance_code'), |
221 | + ('reconfigure', 'address_contact_name'), |
222 | + ('reconfigure', 'address_street'), |
223 | + ('reconfigure', 'address_street2'), |
224 | + ('reconfigure', 'address_zip'), |
225 | + ('reconfigure', 'address_city'), |
226 | + ('reconfigure', 'address_country'), |
227 | + ('reconfigure', 'address_phone'), |
228 | + ('reconfigure', 'address_email'), |
229 | + ('reconfigure', 'delivery_process'), |
230 | + ('reconfigure', 'functional_currency'), |
231 | + ) |
232 | + for section, option in not_empty_string_option_list: |
233 | + self.check_not_empty_string(config, section, option) |
234 | + if self.msg: |
235 | + return |
236 | + |
237 | + # check mandatory integer values |
238 | + not_empty_int_option_list = ( |
239 | + ('backup', 'auto_bck_interval_nb'), |
240 | + ('partner', 'external_account_receivable'), |
241 | + ('partner', 'external_account_payable'), |
242 | + ('partner', 'internal_account_receivable'), |
243 | + ('partner', 'internal_account_payable'), |
244 | + ('company', 'default_counterpart'), |
245 | + ('company', 'salaries_default_account'), |
246 | + ('company', 'rebilling_intersection_account'), |
247 | + ('company', 'intermission_counterpart'), |
248 | + ('company', 'counterpart_bs_debit_balance'), |
249 | + ('company', 'counterpart_bs_crebit_balance'), |
250 | + ('company', 'debit_account_pl_positive'), |
251 | + ('company', 'credit_account_pl_negative'), |
252 | + ('company', 'scheduler_range_days'), |
253 | + ) |
254 | + for section, option in not_empty_int_option_list: |
255 | + self.check_mandatory_int(config, section, option) |
256 | + if self.msg: |
257 | + return |
258 | + |
259 | + # check value is in possibles values |
260 | + possible_value_list = ( |
261 | + ('instance', 'instance_level', ('coordo', 'project')), |
262 | + ('instance', 'lang', ('fr_MF', 'es_MF', 'en_MF')), |
263 | + ('backup', 'auto_bck_interval_unit', ('minutes', 'hours', 'work_days', 'days', 'weeks', 'months')), |
264 | + ('reconfigure', 'delivery_process', ('complex', 'simple')), |
265 | + ) |
266 | + |
267 | + for section, option, possible_values in possible_value_list: |
268 | + self.check_possible_value(config, section, option, possible_values) |
269 | + if self.msg: |
270 | + return |
271 | + |
272 | + except NoOptionError as e: |
273 | + self.msg = {'message': ustr(_('No option \'%s\' found for the section \'[%s]\' in the config file \'%s\'') % (e.option, e.section, file_path)), |
274 | + 'title': ustr(_('Option missing in configuration file'))} |
275 | + return |
276 | + except NoSectionError as e: |
277 | + self.msg = {'message': ustr(_('No section \'%s\' found in the config file \'%s\'') % (e.section, file_path)), |
278 | + 'title': ustr(_('Option missing in configuration file'))} |
279 | + return |
280 | + |
281 | + def database_creation(self, password, dbname, admin_password): |
282 | + try: |
283 | + res = rpc.session.execute_db('create', password, dbname, False, 'en_US', admin_password) |
284 | + while True: |
285 | + try: |
286 | + progress, users = rpc.session.execute_db('get_progress', password, res) |
287 | + if progress == 1.0: |
288 | + for x in users: |
289 | + if x['login'] == 'admin': |
290 | + rpc.session.login(dbname, 'admin', x['password']) |
291 | + ok = True |
292 | + break |
293 | + else: |
294 | + time.sleep(1) |
295 | + except Exception as e: |
296 | + raise DatabaseCreationCrash() |
297 | + except DatabaseCreationCrash: |
298 | + self.msg = {'message': (_("The server crashed during installation.\nWe suggest you to drop this database.")), |
299 | + 'title': (_('Error during database creation'))} |
300 | + except openobject.errors.AccessDenied, e: |
301 | + self.msg = {'message': _('Bad super admin password'), |
302 | + 'title' : e.title} |
303 | + |
304 | + def background_auto_creation(self, password, dbname, db_exists, config_dict): |
305 | + if not db_exists: |
306 | + # create database |
307 | + self.database_creation(password, dbname, config_dict['instance'].get('admin_password')) |
308 | + |
309 | + rpc.session.execute_db('instance_auto_creation', password, dbname) |
310 | + self.resume, self.progress, self.state, self.error, monitor_status = rpc.session.execute_db('creation_get_resume_progress', dbname) |
311 | + |
312 | + @expose() |
313 | + @validate(form=_FORMS['auto_create']) |
314 | + @error_handler(auto_create) |
315 | + def do_auto_create(self, password, **kw): |
316 | + self.msg = {} |
317 | + self.progress = 0.03 |
318 | + self.state = 'draft' |
319 | + try: |
320 | + config_file_name = 'uf_auto_install.conf' |
321 | + if sys.platform == 'win32': |
322 | + config_file_path = os.path.join(paths.root(), '..', 'UFautoInstall', config_file_name) |
323 | + else: |
324 | + config_file_path = os.path.join(paths.root(), '..', 'unifield-server', 'UFautoInstall', config_file_name) |
325 | + |
326 | + self.check_config_file(config_file_path) |
327 | + if self.msg: |
328 | + return self.auto_create() |
329 | + config = ConfigParser.ConfigParser() |
330 | + config.read(config_file_path) |
331 | + |
332 | + config_dict = {x:dict(config.items(x)) for x in config.sections()} |
333 | + dbname = config_dict['instance'].get('db_name') |
334 | + db_exists = False |
335 | + |
336 | + # check the database not already exists |
337 | + if dbname in get_db_list(): |
338 | + db_exists = True |
339 | + self.resume = _('Database with this name exists, resume from the last point...\n') |
340 | + else: |
341 | + self.resume = _('Empty database creation in progress...\n') |
342 | + #raise DatabaseExist |
343 | + |
344 | + create_thread = threading.Thread(target=self.background_auto_creation, |
345 | + args=(password, dbname, db_exists, |
346 | + config_dict)) |
347 | + create_thread.start() |
348 | + create_thread.join(0.5) |
349 | + |
350 | + except openobject.errors.AccessDenied, e: |
351 | + self.msg = {'message': _('Wrong password'), |
352 | + 'title' : e.title} |
353 | + except DatabaseExist: |
354 | + pass |
355 | + #self.msg = {'message': ustr(_('The database already exist')), |
356 | + # 'title': 'Database exist'} |
357 | + except Exception as e: |
358 | + self.msg = {'message' : _("Could not auto create database: %s") % e} |
359 | + |
360 | + if self.msg: |
361 | + return self.auto_create() |
362 | + return self.auto_create_progress() |
363 | + |
364 | @expose(template="/openerp/controllers/templates/database.mako") |
365 | def drop(self, tg_errors=None, **kw): |
366 | form = _FORMS['drop'] |
367 | |
368 | === added file 'addons/openerp/controllers/templates/auto_create.mako' |
369 | --- addons/openerp/controllers/templates/auto_create.mako 1970-01-01 00:00:00 +0000 |
370 | +++ addons/openerp/controllers/templates/auto_create.mako 2017-11-21 17:05:56 +0000 |
371 | @@ -0,0 +1,70 @@ |
372 | +<%inherit file="/openerp/controllers/templates/base_dispatch.mako"/> |
373 | +<%def name="current_for(name)"><% |
374 | + if form.name == name: context.write('current') |
375 | +%></%def> |
376 | +<%def name="header()"> |
377 | + <title>${form.string}</title> |
378 | + |
379 | + <script type="text/javascript" src="/openerp/static/javascript/openerp/openerp.ui.waitbox.js"></script> |
380 | + <link rel="stylesheet" type="text/css" href="/openerp/static/css/waitbox.css"/> |
381 | + <link rel="stylesheet" type="text/css" href="/openerp/static/css/database.css"/> |
382 | + <script type="text/javascript"> |
383 | + function on_create() { |
384 | + new openerp.ui.WaitBox().showAfter(2000); |
385 | + return true; |
386 | + } |
387 | + </script> |
388 | + % if error: |
389 | + <script type="text/javascript"> |
390 | + var $error_tbl = jQuery('<table class="errorbox">'); |
391 | + $error_tbl.append('<tr><td style="padding: 4px 2px;" width="10%"><img src="/openerp/static/images/warning.png"></td><td class="error_message_content">${error["message"]}</td></tr>'); |
392 | + $error_tbl.append('<tr><td style="padding: 0 8px 5px 0; vertical-align:top;" align="right" colspan="2"><a class="button-a" id="error_btn" onclick="$error_tbl.dialog(\'close\');">OK</a></td></tr>'); |
393 | + |
394 | + jQuery(document).ready(function () { |
395 | + jQuery(document.body).append($error_tbl); |
396 | + var error_dialog_options = { |
397 | + modal: true, |
398 | + resizable: false, |
399 | + title: '<div class="error_message_header">${error.get("title", "Warning")}</div>' |
400 | + }; |
401 | + % if error.get('redirect_to'): |
402 | + error_dialog_options['close'] = function( event, ui ) { |
403 | + $(location).attr('href','${error['redirect_to']}'); |
404 | + }; |
405 | + % endif |
406 | + $error_tbl.dialog(error_dialog_options); |
407 | + }) |
408 | + </script> |
409 | + % endif |
410 | +</%def> |
411 | + |
412 | +<%def name="content()"> |
413 | + <table width="100%"> |
414 | + <tr><%include file="header.mako"/></tr> |
415 | + </table> |
416 | + <div class="db-form"> |
417 | + <h1>Automated instance creation detected</h1> |
418 | + |
419 | + <div class='auto_instance_text'> |
420 | + <p>If you have checked the following points, you can start the |
421 | +process of instance auto creation by login with the Super admin password. Points to check: |
422 | + <ul> |
423 | + <li>A Folder 'UFautoInstall' is present in Unifield/Server folder.</li> |
424 | + <li>This folder contain a file 'uf_auto_install.conf'</li> |
425 | + <li>This file is correct (required fields, correct values)</li> |
426 | + <li>The folder also contain an 'import' directory |
427 | +(Unifield/Server/UFautoInstall/import)</li> |
428 | + <li>This 'import' directory contain files where the name of |
429 | +the file is the model to import and the extension is csv (typically, |
430 | +'account.analytic.journal.csv' and 'account.journal.csv')</li> |
431 | + <li>The connexion to the SYNC_SERVER is ok (credentials, |
432 | +address, port, ...)</li> |
433 | + <li>The parents instance (HQ, and Coordo if it is a |
434 | +project) exists and are present as instance in the SYNC_SERVER</li> |
435 | + </ul> |
436 | + </p> |
437 | + </div> |
438 | + <div>${form.display()}</div> |
439 | + </div> |
440 | +<%include file="footer.mako"/> |
441 | +</%def> |
442 | |
443 | === added file 'addons/openerp/controllers/templates/auto_create_progress.mako' |
444 | --- addons/openerp/controllers/templates/auto_create_progress.mako 1970-01-01 00:00:00 +0000 |
445 | +++ addons/openerp/controllers/templates/auto_create_progress.mako 2017-11-21 17:05:56 +0000 |
446 | @@ -0,0 +1,80 @@ |
447 | +<%inherit file="/openerp/controllers/templates/base_dispatch.mako"/> |
448 | +<%def name="header()"> |
449 | + <title>Instance creation progression</title> |
450 | + |
451 | + <script type="text/javascript" src="/openerp/static/javascript/openerp/openerp.ui.waitbox.js"></script> |
452 | + <script type="text/javascript"> |
453 | + $(document).ready(function(){ |
454 | + interval = setInterval(function() |
455 | + { |
456 | + $.ajax({ |
457 | + type: 'get', |
458 | + dataType: "json", |
459 | + url: 'get_auto_create_progress', |
460 | + success: function (data) { |
461 | + |
462 | + if (data){ |
463 | + if (data.error){ |
464 | + clearInterval(interval); |
465 | + var $error_tbl = jQuery('<table class="errorbox">'); |
466 | + $error_tbl.append('<tr><td style="padding: 4px 2px;" width="10%"><img src="/openerp/static/images/warning.png"></td><td class="error_message_content">' + data.error + '</td></tr>'); |
467 | + $error_tbl.append('<tr><td style="padding: 0 8px 5px 0; vertical-align:top;" align="right" colspan="2"><a class="button-a" id="error_btn" onclick="$error_tbl.dialog(\'close\');">OK</a></td></tr>'); |
468 | + |
469 | + jQuery(document).ready(function () { |
470 | + jQuery(document.body).append($error_tbl); |
471 | + var error_dialog_options = { |
472 | + modal: true, |
473 | + resizable: false, |
474 | + title: '<div class="error_message_header">Error</div>' |
475 | + }; |
476 | + $error_tbl.dialog(error_dialog_options); |
477 | + }) |
478 | + |
479 | + }; |
480 | + $("div.auto_creation_resume textarea").val(data.resume); |
481 | + $("div.progressbar").text((data.progress*100).toPrecision(3)+'%'); |
482 | + $("div.progressbar").css({"width":(data.progress*100).toPrecision(3)+'%'}); |
483 | + $("div.my_state").text(data.state); |
484 | + if (data.state === 'done') { |
485 | + clearInterval(interval); |
486 | + }; |
487 | + if (data.monitor_status) { |
488 | + $("div.my_monitor_status").text(data.monitor_status); |
489 | + }; |
490 | + } |
491 | + }, |
492 | + error: function (xhr, status, error) { |
493 | + } |
494 | + }); |
495 | + }, 3000) |
496 | + }); |
497 | + </script> |
498 | + |
499 | + <link rel="stylesheet" type="text/css" href="/openerp/static/css/waitbox.css"/> |
500 | + <link rel="stylesheet" type="text/css" href="/openerp/static/css/database.css"/> |
501 | + |
502 | +</%def> |
503 | + |
504 | +<%def name="content()"> |
505 | + <table width="100%"> |
506 | + <tr><%include file="header.mako"/></tr> |
507 | + </table> |
508 | + |
509 | + |
510 | + |
511 | + <div class="db-form"> |
512 | + <h1>Automated instance creation in progress...</h1> |
513 | + |
514 | + <div class="my_state"></div> |
515 | + <div class="my_monitor_status"></div> |
516 | + |
517 | + <div class="instance_creation_progress"> |
518 | + <div class="progressbar" style="width:${'%d'%(percent*100)}%">${'%d'%(percent*100)}%</div> |
519 | + </div> |
520 | + |
521 | + <div class="auto_creation_resume"> |
522 | + <textarea rows="20" cols="80">${resume}</textarea> |
523 | + </div> |
524 | + </div> |
525 | +<%include file="footer.mako"/> |
526 | +</%def> |
527 | |
528 | === modified file 'addons/openerp/controllers/utils.py' |
529 | --- addons/openerp/controllers/utils.py 2016-11-17 15:29:41 +0000 |
530 | +++ addons/openerp/controllers/utils.py 2017-11-21 17:05:56 +0000 |
531 | @@ -20,11 +20,13 @@ |
532 | ############################################################################### |
533 | import re |
534 | import os |
535 | +import sys |
536 | |
537 | import cherrypy |
538 | from openerp.utils import rpc |
539 | |
540 | from openobject import tools |
541 | +from openobject import paths |
542 | from openobject.tools import expose, redirect |
543 | import openobject |
544 | |
545 | @@ -94,6 +96,16 @@ |
546 | url = rpc.session.connection_string |
547 | url = str(url[:-1]) |
548 | |
549 | + config_file_name = 'uf_auto_install.conf' |
550 | + if sys.platform == 'win32': |
551 | + config_file_path = os.path.join(paths.root(), '..', 'UFautoInstall', config_file_name) |
552 | + else: |
553 | + config_file_path = os.path.join(paths.root(), '..', 'unifield-server', 'UFautoInstall', config_file_name) |
554 | + if os.path.exists(config_file_path): |
555 | + raise redirect('/openerp/database/auto_create') |
556 | + return auto_install(target, db, user, password, action, message, |
557 | + origArgs, url) |
558 | + |
559 | result = get_db_list() |
560 | dblist = result['dblist'] |
561 | bad_regional = result['bad_regional'] |
562 | |
563 | === modified file 'addons/openerp/po/messages/fr.po' |
564 | --- addons/openerp/po/messages/fr.po 2017-10-27 14:32:19 +0000 |
565 | +++ addons/openerp/po/messages/fr.po 2017-11-21 17:05:56 +0000 |
566 | @@ -275,7 +275,7 @@ |
567 | |
568 | #: controllers/database.py:173 |
569 | msgid "You must avoid all accents, space or special characters." |
570 | -msgstr "Les accents , espaces et caractères spéciaux ne sont pas autorisés ." |
571 | +msgstr "Les accents, espaces et caractères spéciaux ne sont pas autorisés ." |
572 | |
573 | #: controllers/database.py:174 |
574 | msgid "Bad database name" |
575 | @@ -648,7 +648,7 @@ |
576 | "données. Il met en relation, améliore et\n" |
577 | " gère les processus dans les domaines des ventes, de la " |
578 | "finance, de la logistique,\n" |
579 | -" de la gestion de projets , la production, les services, " |
580 | +" de la gestion de projets, la production, les services, " |
581 | "la gestion de la relation client, etc.\n" |
582 | " " |
583 | |
584 | |
585 | === modified file 'addons/openerp/static/css/database.css' |
586 | --- addons/openerp/static/css/database.css 2012-11-15 08:31:02 +0000 |
587 | +++ addons/openerp/static/css/database.css 2017-11-21 17:05:56 +0000 |
588 | @@ -69,3 +69,27 @@ |
589 | text-align: right; |
590 | padding: 0 5px 0 0; |
591 | } |
592 | + |
593 | +.instance_creation_progress { |
594 | + width: 20%; |
595 | + margin-left: 40%; |
596 | + margin-top: 2em; |
597 | + margin-bottom: 2em; |
598 | + border: solid 1px lightslategrey; |
599 | +} |
600 | + |
601 | +.instance_creation_progress .progressbar { |
602 | + background-color: #4CAF50; |
603 | + text-align: center; |
604 | + font-size: 15px; |
605 | + line-height: 2; |
606 | +} |
607 | + |
608 | +.auto_creation_resume { |
609 | + text-align: center; |
610 | +} |
611 | + |
612 | +.auto_instance_text { |
613 | + font-size: 1.5em; |
614 | + margin: 3em; |
615 | +} |