410
410
return {"db_list": dbs}
412
412
@openerpweb.jsonrequest
413
def progress(self, req, password, id):
414
return req.session.proxy('db').get_progress(password, id)
416
@openerpweb.jsonrequest
417
413
def create(self, req, fields):
419
414
params = dict(map(operator.itemgetter('name', 'value'), fields))
421
416
params['super_admin_pwd'],
425
420
params['create_admin_pwd']
429
return req.session.proxy("db").create(*create_attrs)
430
except xmlrpclib.Fault, e:
431
if e.faultCode and isinstance(e.faultCode, str)\
432
and e.faultCode.split(':')[0] == 'AccessDenied':
433
return {'error': e.faultCode, 'title': 'Database creation error'}
435
'error': "Could not create database '%s': %s" % (
436
params['db_name'], e.faultString),
437
'title': 'Database creation error'
423
return req.session.proxy("db").create_database(*create_attrs)
440
425
@openerpweb.jsonrequest
441
426
def drop(self, req, fields):
487
472
return {'error': e.faultCode, 'title': 'Change Password'}
488
473
return {'error': 'Error, password not changed !', 'title': 'Change Password'}
475
def topological_sort(modules):
476
""" Return a list of module names sorted so that their dependencies of the
477
modules are listed before the module itself
479
modules is a dict of {module_name: dependencies}
481
:param modules: modules to sort
486
dependencies = set(itertools.chain.from_iterable(modules.itervalues()))
487
# incoming edge: dependency on other module (if a depends on b, a has an
488
# incoming edge from b, aka there's an edge from b to a)
489
# outgoing edge: other module depending on this one
491
# [Tarjan 1976], http://en.wikipedia.org/wiki/Topological_sorting#Algorithms
492
#L ← Empty list that will contain the sorted nodes
494
#S ← Set of all nodes with no outgoing edges (modules on which no other
496
S = set(module for module in modules if module not in dependencies)
499
#function visit(node n)
501
#if n has not been visited yet then
505
#change: n not web module, can not be resolved, ignore
506
if n not in modules: return
507
#for each node m with an edge from m to n do (dependencies of n)
513
#for each node n in S do
490
519
class Session(openerpweb.Controller):
491
520
_cp_path = "/web/session"
554
583
def modules(self, req):
555
584
# Compute available candidates module
556
585
loadable = openerpweb.addons_manifest
557
loaded = req.config.server_wide_modules
586
loaded = set(req.config.server_wide_modules)
558
587
candidates = [mod for mod in loadable if mod not in loaded]
560
# Compute active true modules that might be on the web side only
561
active = set(name for name in candidates
562
if openerpweb.addons_manifest[name].get('active'))
589
# already installed modules have no dependencies
590
modules = dict.fromkeys(loaded, [])
592
# Compute auto_install modules that might be on the web side only
593
modules.update((name, openerpweb.addons_manifest[name].get('depends', []))
594
for name in candidates
595
if openerpweb.addons_manifest[name].get('auto_install'))
564
597
# Retrieve database installed modules
565
598
Modules = req.session.model('ir.module.module')
566
installed = set(module['name'] for module in Modules.search_read(
567
[('state','=','installed'), ('name','in', candidates)], ['name']))
599
for module in Modules.search_read(
600
[('state','=','installed'), ('name','in', candidates)],
601
['name', 'dependencies_id']):
602
deps = module.get('dependencies_id')
605
operator.itemgetter('name'),
606
req.session.model('ir.module.module.dependency').read(deps, ['name']))
607
modules[module['name']] = list(
608
set(modules.get(module['name'], []) + dependencies))
570
return list(active | installed)
610
sorted_modules = topological_sort(modules)
611
return [module for module in sorted_modules if module not in loaded]
572
613
@openerpweb.jsonrequest
573
614
def eval_domain_and_context(self, req, contexts, domains,
1304
1345
filters = Model.get_filters(model)
1305
1346
for filter in filters:
1307
filter["context"] = req.session.eval_context(
1308
parse_context(filter["context"], req.session))
1309
filter["domain"] = req.session.eval_domain(
1310
parse_domain(filter["domain"], req.session))
1348
parsed_context = parse_context(filter["context"], req.session)
1349
filter["context"] = (parsed_context
1350
if not isinstance(parsed_context, common.nonliterals.BaseContext)
1351
else req.session.eval_context(parsed_context))
1353
parsed_domain = parse_domain(filter["domain"], req.session)
1354
filter["domain"] = (parsed_domain
1355
if not isinstance(parsed_domain, common.nonliterals.BaseDomain)
1356
else req.session.eval_domain(parsed_domain))
1311
1357
except Exception:
1312
1358
logger.exception("Failed to parse custom filter %s in %s",
1313
1359
filter['name'], model)
1340
1386
ctx = common.nonliterals.CompoundContext(context_to_save)
1341
1387
ctx.session = req.session
1342
1388
ctx = ctx.evaluate()
1389
ctx['dashboard_merge_domains_contexts'] = False # TODO: replace this 6.1 workaround by attribute on <action/>
1343
1390
domain = common.nonliterals.CompoundDomain(domain)
1344
1391
domain.session = req.session
1345
1392
domain = domain.evaluate()