Add pool to wizard and first wizard for module (update list)

This commit is contained in:
ced@b2ck.com committed 2007-12-29 00:35:21 +01:00
1 parent 78f9d1e820
commit 72211bb8bf
6 files changed
+305 -108

No files matched your search

+87
View File
@@ -7,6 +7,7 @@ from trytond.osv import fields, OSV
import trytond.tools as tools
from trytond.module import ADDONS_PATH
from trytond.osv.orm import ExceptORM
from trytond.wizard import Wizard
VER_REGEXP = re.compile(
"^(\\d+)((\\.\\d+)*)([a-z]?)((_(pre|p|beta|alpha|rc)\\d*)*)(-r(\\d+))?$")
@@ -536,3 +537,89 @@ class ModuleDependency(OSV):
}
ModuleDependency()
class ModuleUpdateList(Wizard):
"Update module list"
_name = 'ir.module.module.update_list'
arch = '''<?xml version="1.0"?>
<form string="Scan for new modules">
<label string="This function will check for new modules in the 'addons' path and on module repositories:" colspan="4" align="0.0"/>
<field name="repositories" colspan="4" nolabel="1"/>
</form>'''
fields = {
'repositories': {'type': 'text', 'string': 'Repositories', 'readonly': True},
}
arch_module = '''<?xml version="1.0"?>
<form string="New modules">
<field name="update" colspan="4"/>
<field name="add" colspan="4"/>
</form>'''
fields_module = {
'update': {'type': 'integer', 'string': 'Number of modules updated', 'readonly': True},
'add': {'type': 'integer', 'string': 'Number of modules added', 'readonly': True},
}
def _update_module(self, cr, uid, data, context):
module_obj = self.pool.get('ir.module.module')
update, add = module_obj.update_list(cr, uid)
return {'update': update, 'add': add}
def _action_module_open(self, cr, uid, data, context):
return {
'domain': str([]),
'name': 'Module List',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'ir.module.module',
'view_id': False,
'type': 'ir.actions.act_window',
}
def _get_repositories(self, cr, uid, data, context):
repository_obj = self.pool.get('ir.module.repository')
ids = repository_obj.search(cr, uid, [])
res = repository_obj.read(cr, uid, ids, ['name', 'url'], context)
return {
'repositories': '\n'.join([x['name']+': '+x['url'] \
for x in res]),
}
states = {
'init': {
'actions': [_get_repositories],
'result': {
'type': 'form',
'arch': arch,
'fields': fields,
'state': [
('end', 'Cancel', 'gtk-cancel'),
('update', 'Check new modules', 'gtk-ok', True),
]
}
},
'update': {
'actions': [_update_module],
'result': {
'type': 'form',
'arch': arch_module,
'fields': fields_module,
'state': [
('open_window', 'Ok', 'gtk-ok', True),
]
}
},
'open_window': {
'actions': [],
'result': {
'type': 'action',
'action': _action_module_open,
'state':'end',
}
},
}
ModuleUpdateList()
+8
View File
@@ -95,5 +95,13 @@
</record>
<menuitem name="Administration/IR/Modules/"
action="act_module_form" id="menu_module_form"/>
<record model="ir.actions.wizard" id="act_module_update_list">
<field name="name">Update Module List</field>
<field name="wiz_name">ir.module.module.update_list</field>
</record>
<menuitem name="Administration/IR/Modules/Update Module List"
action="act_module_update_list"
type="wizard"
id="menu_module_update_list"/>
</data>
</terp>
+2
View File
@@ -168,6 +168,8 @@ def load_module_graph(cursor, graph, **kwargs):
sys.stdout.flush()
pool = pooler.get_pool(cursor.dbname)
modules = pool.instanciate(module)
pool_wizard = pooler.get_pool_wizard(cursor.dbname)
wizards = pool_wizard.instanciate(module, pool)
cursor.execute('SELECT state, demo FROM ir_module_module WHERE name = %s',
(module,))
(package_state, package_demo) = (cursor.rowcount and cursor.fetchone()) \
+15 -1
View File
@@ -3,8 +3,10 @@ from netsvc import Logger, LOG_INFO
_DB = {}
_POOL = {}
_POOL_WIZARD = {}
def get_db_and_pool(db_name, force_demo=False, update_module=False):
def get_db_and_pool(db_name, force_demo=False, update_module=False,
wizard=False):
if db_name in _DB:
database = _DB[db_name]
else:
@@ -15,12 +17,18 @@ def get_db_and_pool(db_name, force_demo=False, update_module=False):
if db_name in _POOL:
pool = _POOL[db_name]
pool_wizard = _POOL_WIZARD[db_name]
else:
Logger().notify_channel('pooler', LOG_INFO,
'Instanciate pooler for %s' % (db_name))
from osv.osv import OSVService
pool = OSVService()
_POOL[db_name] = pool
from wizard import WizardService
pool_wizard = WizardService()
_POOL_WIZARD[db_name] = pool_wizard
from module import load_modules
load_modules(database, force_demo, update_module)
@@ -28,6 +36,8 @@ def get_db_and_pool(db_name, force_demo=False, update_module=False):
import report
#report.interface.register_all(database)
pool.get('ir.cron').pool_jobs(database.dbname)
if wizard:
return database, pool_wizard
return database, pool
def restart_pool(db_name, force_demo=False, update_module=False):
@@ -57,3 +67,7 @@ def get_db(db_name):
def get_pool(db_name, force_demo=False, update_module=False):
pool = get_db_and_pool(db_name, force_demo, update_module)[1]
return pool
def get_pool_wizard(db_name, force_demo=False, update_module=False):
pool = get_db_and_pool(db_name, force_demo, update_module, wizard=True)[1]
return pool
+3 -3
View File
@@ -16,9 +16,9 @@ class Wizard(Service):
def _execute(self, database, user, wiz_id, datas, action, context):
self.wiz_datas[wiz_id].update(datas)
wiz = LocalService('wizard.' + self.wiz_name[wiz_id])
return wiz.execute(database, user, self.wiz_datas[wiz_id], action,
context)
wiz = LocalService('wizard_proxy')
return wiz.execute(database, user, self.wiz_name[wiz_id],
self.wiz_datas[wiz_id], action, context)
def create(self, database, user, passwd, wiz_name, datas=None):
security.check(database, user, passwd)
+190 -104
View File
@@ -6,6 +6,11 @@ from xml import dom
from trytond.osv import ExceptORM, ExceptOSV
import sys
MODULE_LIST = []
MODULE_CLASS_LIST = {}
CLASS_POOL = {}
class ExceptWizard(Exception):
def __init__(self, name, value):
Exception.__init__(self)
@@ -16,107 +21,23 @@ class ExceptWizard(Exception):
except_wizard = ExceptWizard
class WizardService(Service):
states = {}
name = ""
def __init__(self):
self.wiz_name = self.name
assert not service_exist(self.wiz_name), \
'The wizard "%s" already exists!' % self.name
Service.__init__(self, self.wiz_name)
self.object_name_pool = {}
self.module_obj_list = {}
Service.__init__(self, 'wizard_proxy')
Service.join_group(self, 'web-services')
Service.export_method(self, self.execute)
def translate_view(self, cursor, node, state, lang):
translation_obj = pooler.get_pool(cursor.dbname).get('ir.translation')
if node.nodeType == node.ELEMENT_NODE:
if node.hasAttribute('string') \
and node.getAttribute('string'):
res_trans = translation_obj._get_source(cursor,
self.wiz_name + ',' + state, 'wizard_view', lang)
if res_trans:
node.setAttribute('string', res_trans.decode('utf8'))
for child_node in node.childNodes:
self.translate_view(cursor, child_node, state, lang)
def execute_cr(self, cursor, user, data, state='init', context=None):
if context is None:
context = {}
res = {}
pool = pooler.get_pool(cursor.dbname)
values_obj = pool.get('ir.values')
translation_obj = pool.get('ir.translation')
def execute_cr(self, cursor, user, wizard_name, data, state='init',
context=None):
try:
state_def = self.states[state]
result_def = copy.copy(state_def.get('result', {}))
# iterate through the list of actions defined for this state
for action in state_def.get('actions', []):
# execute them
action_res = action(self, cursor, user, data, context)
assert isinstance(action_res, dict), \
'The return value of wizard actions ' \
'should be a dictionary'
result_def.update(action_res)
res['datas'] = result_def.get('datas', {})
lang = context.get('lang', 'en_US')
if result_def['type'] == 'action':
res['action'] = result_def['action'](self, cursor, user, data,
context)
elif result_def['type'] == 'form':
fields = copy.copy(result_def['fields'])
arch = copy.copy(result_def['arch'])
button_list = copy.copy(result_def['state'])
defaults = values_obj.get(cursor, user, 'default',
False, [('wizard.'+self.wiz_name, False)])
default_values = dict([(x[1], x[2]) for x in defaults])
for val in fields.keys():
if 'default' in fields[val]:
# execute default method for this field
if callable(fields[val]['default']):
fields[val]['value'] = fields[val]['default']\
(self, cursor, user, data, state, context)
else:
fields[val]['value'] = fields[val]['default']
del fields[val]['default']
if val in default_values:
fields[val]['value'] = default_values[val]
if 'selection' in fields[val]:
if callable(fields[val]['selection']):
fields[val] = copy.copy(fields[val])
fields[val]['selection'] = fields[val]['selection']\
(self, cursor, user, data, state, context)
# translate fields
for field in fields:
res_trans = translation_obj._get_source(cursor, user,
self.wiz_name + ',' + state + ',' + field,
'wizard_field', lang)
if res_trans:
fields[field]['string'] = res_trans
# translate arch
doc = dom.minidom.parseString(arch)
self.translate_view(cursor, doc, state, lang)
arch = doc.toxml()
# translate buttons
for i, button in enumerate(button_list):
button_name = button[0]
res_trans = translation_obj._get_source(cursor, user,
self.wiz_name + ',' + state + ',' + button_name,
'wizard_button', lang)
if res_trans:
button = list(button)
button[1] = res_trans
button_list[i] = tuple(button)
res['fields'] = fields
res['arch'] = arch
res['state'] = button_list
wizard = pooler.get_pool_wizard(cursor.dbname).get(wizard_name)
if not wizard:
self.abort_response('Wizard Error', 'warning',
'Wizard %s doesn\'t exist' % str(wizard_name))
res = wizard.execute(cursor, user, data, state, context)
return res
except ExceptORM, inst:
self.abort_response(inst.name, 'warning', inst.value)
except ExceptOSV, inst:
@@ -131,17 +52,14 @@ class WizardService(Service):
'Exception in call: ' + tb_s)
raise
if result_def['type'] == 'choice':
next_state = result_def['next_state'](self, cursor, user,
data, context)
return self.execute_cr(cursor, user, data, next_state, context)
return res
def execute(self, dbname, user, data, state='init', context=None):
def execute(self, dbname, user, wizard_name, data, state='init',
context=None):
cursor = pooler.get_db(dbname).cursor()
pool = pooler.get_pool_wizard(dbname)
try:
try:
res = self.execute_cr(cursor, user, data, state, context)
res = pool.execute_cr(cursor, user, wizard_name, data, state,
context)
cursor.commit()
except Exception:
cursor.rollback()
@@ -149,3 +67,171 @@ class WizardService(Service):
finally:
cursor.close()
return res
def add(self, name, object_name_inst):
"""
adds a new obj instance to the obj pool.
if it already existed, the instance is replaced
"""
if self.object_name_pool.has_key(name):
del self.object_name_pool[name]
self.object_name_pool[name] = object_name_inst
module = str(object_name_inst.__class__)[6:]
module = module[:len(module)-1]
module = module.split('.')[0][2:]
self.module_obj_list.setdefault(module, []).append(object_name_inst)
def get(self, name):
return self.object_name_pool.get(name, None)
def instanciate(self, module, pool_obj):
res = []
class_list = MODULE_CLASS_LIST.get(module, [])
for klass in class_list:
res.append(klass.create_instance(self, module, pool_obj))
return res
class Wizard(object):
_name = ""
states = {}
def __new__(cls):
for module in cls.__module__.split('.'):
if module != 'trytond' and module != 'addons':
break
if not hasattr(cls, '_module'):
cls._module = module
MODULE_CLASS_LIST.setdefault(cls._module, []).append(cls)
CLASS_POOL[cls._name] = cls
if module not in MODULE_LIST:
MODULE_LIST.append(cls._module)
return None
def create_instance(cls, pool, module, pool_obj):
"""
try to apply inheritancy at the instanciation level and
put objs in the pool var
"""
if pool.get(cls._name):
parent_class = pool.get(cls._name).__class__
new_states = copy.copy(getattr(pool.get(cls._name), 'states'))
for i in (
'actions',
'result',
):
new = copy.copy(getattr(new_states, i))
if hasattr(new, 'update'):
new.update(cls.__dict__.get(i, {}))
else:
new.extend(cls.__dict__.get(i, []))
new_states[i] = new
cls = type(cls._name, (cls, parent_class), {'states': new_states})
obj = object.__new__(cls)
obj.__init__(pool, pool_obj)
return obj
create_instance = classmethod(create_instance)
def __init__(self, pool, pool_obj):
pool.add(self._name, self)
self.pool = pool_obj
super(Wizard, self).__init__()
def translate_view(self, cursor, node, state, lang):
translation_obj = pooler.get_pool(cursor.dbname).get('ir.translation')
if node.nodeType == node.ELEMENT_NODE:
if node.hasAttribute('string') \
and node.getAttribute('string'):
res_trans = translation_obj._get_source(cursor,
self._name + ',' + state, 'wizard_view', lang)
if res_trans:
node.setAttribute('string', res_trans.decode('utf8'))
for child_node in node.childNodes:
self.translate_view(cursor, child_node, state, lang)
def execute(self, cursor, user, data, state='init', context=None):
if context is None:
context = {}
res = {}
values_obj = self.pool.get('ir.values')
translation_obj = self.pool.get('ir.translation')
state_def = self.states[state]
result_def = copy.copy(state_def.get('result', {}))
# iterate through the list of actions defined for this state
for action in state_def.get('actions', []):
# execute them
action_res = action(self, cursor, user, data, context)
assert isinstance(action_res, dict), \
'The return value of wizard actions ' \
'should be a dictionary'
result_def.update(action_res)
res = copy.copy(result_def)
res['datas'] = result_def.get('datas', {})
lang = context.get('lang', 'en_US')
if result_def['type'] == 'action':
res['action'] = result_def['action'](self, cursor, user, data,
context)
elif result_def['type'] == 'form':
fields = copy.copy(result_def['fields'])
arch = copy.copy(result_def['arch'])
button_list = copy.copy(result_def['state'])
defaults = values_obj.get(cursor, user, 'default',
False, [(self._name, False)])
default_values = dict([(x[1], x[2]) for x in defaults])
for val in fields.keys():
if 'default' in fields[val]:
# execute default method for this field
if callable(fields[val]['default']):
fields[val]['value'] = fields[val]['default']\
(self, cursor, user, data, state, context)
else:
fields[val]['value'] = fields[val]['default']
del fields[val]['default']
if val in default_values:
fields[val]['value'] = default_values[val]
if 'selection' in fields[val]:
if callable(fields[val]['selection']):
fields[val] = copy.copy(fields[val])
fields[val]['selection'] = fields[val]['selection']\
(self, cursor, user, data, state, context)
# translate fields
for field in fields:
res_trans = translation_obj._get_source(cursor, user,
self._name + ',' + state + ',' + field,
'wizard_field', lang)
if res_trans:
fields[field]['string'] = res_trans
# translate arch
doc = dom.minidom.parseString(arch)
self.translate_view(cursor, doc, state, lang)
arch = doc.toxml()
# translate buttons
for i, button in enumerate(button_list):
button_name = button[0]
res_trans = translation_obj._get_source(cursor, user,
self._name + ',' + state + ',' + button_name,
'wizard_button', lang)
if res_trans:
button = list(button)
button[1] = res_trans
button_list[i] = tuple(button)
res['fields'] = fields
res['arch'] = arch
res['state'] = button_list
if result_def['type'] == 'choice':
next_state = result_def['next_state'](self, cursor, user,
data, context)
return self.execute(cursor, user, data, next_state, context)
return res