[MERGE] from trunk

bzr revid: chm@openerp.com-20130329143357-t9jh49676giyxhwe
This commit is contained in:
Christophe Matthieu 2013-03-29 15:33:57 +01:00
commit 40844a0645
71 changed files with 846 additions and 714 deletions

View File

@ -13,3 +13,4 @@ Modules
03_module_dev_04
03_module_dev_05
03_module_dev_06
report-declaration

View File

@ -6,6 +6,9 @@ Changelog
`trunk`
-------
- Almost removed ``LocalService()``. For reports,
``openerp.osv.orm.Model.print_report()`` can be used. For workflows, see
:ref:`orm-workflows`.
- Removed support for the ``NET-RPC`` protocol.
- Added the :ref:`Long polling <longpolling-worker>` worker type.
- Added :ref:`orm-workflows` to the ORM.

View File

@ -0,0 +1,303 @@
.. _form-view-guidelines:
Form Views Guidelines
=====================
Authors: Aline Preillon, Raphael Collet
This document presents functional and technical guidelines for
creating/organizing form views in OpenERP version 7.0. For each item, both the
functional and technical aspects are explained. The goal of the new style of
forms is to make OpenERP easier to use, and to guide users through the system.
Business Views
--------------
Business views are targeted at regular users, not advanced users. Examples
are: Opportunities, Products, Partners, Tasks, Projects, etc.
.. image:: /form-view-guidelines/oppreadonly.png
In general, a business view is composed of
1. a status bar on top (with technical or business flow),
2. a sheet in the middle (the form itself),
3. a bottom part with History and Comments.
Technically, the new form views are structured as follows in XML::
<form version=”7.0”>
<header> ... content of the status bar ... </header>
<sheet> ... content of the sheet ... </sheet>
<div class=”oe_chatter”> ... content of the bottom part ... </div>
</form>
The Status Bar
''''''''''''''
The purpose of the status bar is to show the status of the record and the
action buttons, which were formerly at the bottom of form views.
.. image:: /form-view-guidelines/status.png
The Buttons
...........
The order of buttons follows the business flow. For instance, in a sale order,
the logical steps are:
1. Send the quotation
2. Confirm the quotation
3. Create the final invoice
4. Send the goods
Highlighted buttons (in red) emphasize the logical next step, to help the user.
It is usually the first active button. On the other end, cancel buttons must
remain grey (normal). For instance, in Invoice, the button “Refund” must never
be red.
Technically, buttons are highlighted by adding the class “oe_highlight”::
<button class=”oe_highlight” name=”...” type=”...” states=”...”/>
The Status
..........
We use the widget “statusbar”, and the current value of the state is shown in
red. One should make visible the states that are common to all flows (for
instance, a sale order begins as a quotation, then we send it, then it becomes
a full sale order, and finally it is done.) Exceptions or states depending on
particular flow are only visible if it is the current one.
.. image:: /form-view-guidelines/status1.png
.. image:: /form-view-guidelines/status2.png
The states are shown following the order used in the field (the list in a
selection field, etc). States that are always visible are indicated by the
attribute statusbar_visible. One can also show some states in a specific color
with statusbar_colors.
::
<field name="state" widget="statusbar"
statusbar_visible="draft,sent,progress,invoiced,done"
statusbar_colors="{shipping_except:red,waiting_date:blue}"/>
The Sheet
'''''''''
All business views should look like a printed sheet:
.. image:: /form-view-guidelines/sheet.png
Technically, the layout of forms version 7.0 is different than former versions.
There is no longer a default “grid” layout; instead the layout is more based on
HTML and CSS. The following conventions are now used:
1. The elements <form> and <page> no longer define groups; the elements inside
are laid out inline. One should use explicit <div> or <group> to create
blocks.
2. By default, the element <group> now defines two columns inside, unless an
attribute col=”n” is used. The columns have the same width (1/n th of the
groups width). Use a <group> element to produce a column of fields.
3. The element <separator string=”XXX”/> on top of a group can be replaced
putting string=”XXX” inside the <group> element.
4. The element <field name=”XXX”/> does not produce a label, except when they
are directly below a <group> element. Use <label for=”XXX”/> to produce
the label of the field.
Sheet Headers
.............
Some sheets have headers with one or more fields, and the labels of those
fields are only shown in edit mode.
+---------------------------------------------+----------------------------------------------+
| View mode | Edit mode |
+---------------------------------------------+----------------------------------------------+
| .. image:: /form-view-guidelines/header.png | .. image:: /form-view-guidelines/header2.png |
+---------------------------------------------+----------------------------------------------+
Use HTML text, <div>, <h1>, <h2>… to produce nice headers, and <label> with the
CSS class “oe_edit_only” to produce the fields label in edit mode. Use the
CSS class “oe_inline” to produce inline fields (not blocks). The form above is
produced by the following XML.
::
<label for="name" class="oe_edit_only"/>
<h1><field name="name"/></h1>
<label for="planned_revenue" class="oe_edit_only"/>
<h2>
<field name="planned_revenue" class="oe_inline"/>
<field name="company_currency" class="oe_inline oe_edit_only"/> at
<field name="probability" class="oe_inline"/> % success rate
</h2>
Button Box
..........
Many relevant actions or links can be directly displayed in the form. For
example, in Opportunity form, the actions “Schedule a Call” and “Schedule a
Meeting” take an important place in the use of the CRM. Instead of placing
them in the “More” menu of the sidebar, put them directly in the sheet as
buttons (on the top right).
.. image:: /form-view-guidelines/header3.png
Technically, the buttons are placed inside a <div> to group them as a block on
the right-hand side of the sheet.
::
<div class="oe_button_box oe_right">
<button string="Schedule/Log Call" name="..." type="action"/>
<button string="Schedule Meeting" name="action_makeMeeting" type="object"/>
</div>
Groups and Titles
.................
A column of fields is now produced with a <group> element, with an optional
title. The title has the same effect as placing an explicit <separator>
element inside the group.
.. image:: /form-view-guidelines/screenshot-03.png
::
<group string="Payment Options">
<field name="writeoff_amount"/>
<field name="payment_option"/>
</group>
It is recommended to have two columns of fields on the form. For this, simply
put the <group> elements that contain the fields inside a <group> element.
To ease view inheritance, it is recommended to put a name=”...” in <group>
elements. Adding fields inside such a group is trivial.
Special Case: Subtotals
~~~~~~~~~~~~~~~~~~~~~~~
Some CSS classes are defined to render subtotals like in invoice forms:
.. image:: /form-view-guidelines/screenshot-00.png
::
<group class="oe_subtotal_footer">
<field name="amount_untaxed"/>
<field name="amount_tax"/>
<field name="amount_total" class="oe_subtotal_footer_separator"/>
<field name="residual" style="margin-top: 10px"/>
</group>
Placeholders and Inline Fields
..............................
Sometimes field labels make the form too complex. One can omit field labels,
and instead put a placeholder inside the field. The placeholder text is
visible only when the field is empty. The placeholder should tell what to
place inside the field, and not be an example.
One can also group fields together by rendering them “inline” inside an
explicit block element like <div>. This allows to group several elements in
place of a field (without its label).
The following example, taken from the Leads form, shows both placeholders and
inline fields (zip and city).
+--------------------------------------------------+----------------------------------------------------+
| Edit mode | View mode |
+--------------------------------------------------+----------------------------------------------------+
| .. image:: /form-view-guidelines/placeholder.png | .. image:: /form-view-guidelines/screenshot-01.png |
+--------------------------------------------------+----------------------------------------------------+
::
<group>
<label for="street" string="Address"/>
<div>
<field name="street" placeholder="Street..."/>
<field name="street2"/>
<div>
<field name="zip" class="oe_inline" placeholder="ZIP"/>
<field name="city" class="oe_inline" placeholder="City"/>
</div>
<field name="state_id" placeholder="State"/>
<field name="country_id" placeholder="Country"/>
</div>
</group>
Images
......
Images, like avatars, should be displayed on the right of the sheet. The
product form looks like:
.. image:: /form-view-guidelines/screenshot-02.png
The form above contains a <sheet> element that starts with::
<field name="product_image" widget="image" class="oe_avatar oe_right"/>
Tags
....
Many2many fields, like categories, are better rendered as a list of tags. Use
the widget “many2many_tags”:
.. image:: /form-view-guidelines/screenshot-04.png
::
<field name="category_id"
widget="many2many_tags"/>
Configuration Forms and Wizards
-------------------------------
Configuration Forms
'''''''''''''''''''
Examples of configuration forms: Stages, Leave Type, etc. This concerns all
menu items under Configuration of each application (like Sales/Configuration).
.. image:: /form-view-guidelines/nosheet.png
For those views, the guidelines are:
1. no header (because no state, no workflow, no button)
2. no sheet
Regular Wizards (Popup)
'''''''''''''''''''''''
Example: “Schedule a Call” from an opportunity.
.. image:: /form-view-guidelines/wizard-popup.png
The guidelines are:
1. avoid separators (the title is already in the popup title bar, so another
separator is not relevant);
2. avoid cancel buttons (user generally close the popup window to get the same
effect);
3. action buttons must be highlighted (red);
4. when there is a text area, use a placeholder instead of a label or a
separator;
5. like in regular form views, put buttons in the <header> element.
Configuration Wizard
''''''''''''''''''''
Example: Settings / Configuration / Sales. The guidelines are:
1. always in line (no popup);
2. no sheet;
3. keep the cancel button (users cannot close the window);
4. the button “Apply” must be red.

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -18,6 +18,7 @@ OpenERP Server
06_misc
deployment-gunicorn
deployment-mod-wsgi
form-view-guidelines
OpenERP Command
'''''''''''''''

View File

@ -0,0 +1,23 @@
.. _report-declaration:
Report declaration
==================
.. versionadded:: 7.1
Before version 7.1, report declaration could be done in two different ways:
either via a ``<report>`` tag in XML, or via such a tag and a class
instanciation in a Python module. Instanciating a class in a Python module was
necessary when a custom parser was used.
In version 7.1, the recommended way to register a report is to use only the
``<report>`` XML tag. The tag can now support an additional ``parser``
attribute. The value for that attibute must be a fully-qualified class name,
without the leading ``openerp.addons.`` namespace.
.. note::
The rational to deprecate the manual class instanciation is to make all
reports visible in the database, have a unique way to declare reports
instead of two, and remove the need to maintain a registry of reports in
memory.

View File

@ -53,5 +53,12 @@ multi_process = False
# Is the server running with gevent.
evented = False
def registry(database_name):
"""
Return the model registry for the given database. If the registry does not
exist yet, it is created on the fly.
"""
return modules.registry.RegistryManager.get(database_name)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -20,19 +20,22 @@
##############################################################################
import logging
import operator
import os
import re
from socket import gethostname
import time
import openerp
from openerp import SUPERUSER_ID
from openerp import netsvc, tools
from openerp import tools
from openerp.osv import fields, osv
import openerp.report.interface
from openerp.report.report_sxw import report_sxw, report_rml
from openerp.tools.config import config
from openerp.tools.safe_eval import safe_eval as eval
from openerp.tools.translate import _
import openerp.workflow
_logger = logging.getLogger(__name__)
@ -85,26 +88,45 @@ class report_xml(osv.osv):
res[report.id] = False
return res
def register_all(self, cr):
"""Report registration handler that may be overridden by subclasses to
add their own kinds of report services.
Loads all reports with no manual loaders (auto==True) and
registers the appropriate services to implement them.
def _lookup_report(self, cr, name):
"""
Look up a report definition.
"""
opj = os.path.join
cr.execute("SELECT * FROM ir_act_report_xml WHERE auto=%s ORDER BY id", (True,))
result = cr.dictfetchall()
reports = openerp.report.interface.report_int._reports
for r in result:
if reports.has_key('report.'+r['report_name']):
continue
if r['report_rml'] or r['report_rml_content_data']:
report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'])
if r['report_xsl']:
report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']))
# First lookup in the deprecated place, because if the report definition
# has not been updated, it is more likely the correct definition is there.
# Only reports with custom parser sepcified in Python are still there.
if 'report.' + name in openerp.report.interface.report_int._reports:
new_report = openerp.report.interface.report_int._reports['report.' + name]
else:
cr.execute("SELECT * FROM ir_act_report_xml WHERE report_name=%s", (name,))
r = cr.dictfetchone()
if r:
if r['report_rml'] or r['report_rml_content_data']:
if r['parser']:
kwargs = { 'parser': operator.attrgetter(r['parser'])(openerp.addons) }
else:
kwargs = {}
new_report = report_sxw('report.'+r['report_name'], r['model'],
opj('addons',r['report_rml'] or '/'), header=r['header'], register=False, **kwargs)
elif r['report_xsl']:
new_report = report_rml('report.'+r['report_name'], r['model'],
opj('addons',r['report_xml']),
r['report_xsl'] and opj('addons',r['report_xsl']), register=False)
else:
raise Exception, "Unhandled report type: %s" % r
else:
raise Exception, "Required report does not exist: %s" % r
return new_report
def render_report(self, cr, uid, res_ids, name, data, context=None):
"""
Look up a report definition and render the report for the provided IDs.
"""
new_report = self._lookup_report(cr, name)
return new_report.create(cr, uid, res_ids, data, context)
_name = 'ir.actions.report.xml'
_inherit = 'ir.actions.actions'
@ -140,6 +162,7 @@ class report_xml(osv.osv):
'report_sxw_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='SXW Content',),
'report_rml_content': fields.function(_report_content, fnct_inv=_report_content_inv, type='binary', string='RML Content'),
'parser': fields.char('Parser Class'),
}
_defaults = {
'type': 'ir.actions.report.xml',
@ -645,12 +668,11 @@ class actions_server(osv.osv):
_logger.warning('Failed to send email to: %s', addresses)
if action.state == 'trigger':
wf_service = netsvc.LocalService("workflow")
model = action.wkf_model_id.model
m2o_field_name = action.trigger_obj_id.name
target_id = obj_pool.read(cr, uid, context.get('active_id'), [m2o_field_name])[m2o_field_name]
target_id = target_id[0] if isinstance(target_id,tuple) else target_id
wf_service.trg_validate(uid, model, int(target_id), action.trigger_name, cr)
openerp.workflow.trg_validate(uid, model, int(target_id), action.trigger_name, cr)
if action.state == 'sms':
#TODO: set the user and password from the system

View File

@ -82,6 +82,7 @@
<group string="Miscellaneous">
<field name="multi"/>
<field name="auto"/>
<field name="parser"/>
</group>
</group>
</page>

View File

@ -123,7 +123,7 @@ class ir_cron(osv.osv):
try:
args = str2tuple(args)
openerp.modules.registry.RegistryManager.check_registry_signaling(cr.dbname)
registry = openerp.pooler.get_pool(cr.dbname)
registry = openerp.registry(cr.dbname)
model = registry.get(model_name)
if model and hasattr(model, method_name):
method = getattr(model, method_name)
@ -223,7 +223,7 @@ class ir_cron(osv.osv):
_logger.debug('Starting job `%s`.', job['name'])
job_cr = db.cursor()
try:
registry = openerp.pooler.get_pool(db_name)
registry = openerp.registry(db_name)
registry[cls._name]._process_job(job_cr, job, lock_cr)
except Exception:
_logger.exception('Unexpected exception while processing cron job %r', job)

View File

@ -41,6 +41,8 @@ import openerp.tools as tools
from openerp.loglevels import ustr
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
class MailDeliveryException(osv.except_osv):
"""Specific exception subclass for mail delivery errors"""
@ -411,7 +413,7 @@ class ir_mail_server(osv.osv):
# Do not actually send emails in testing mode!
if getattr(threading.currentThread(), 'testing', False):
_logger.log(logging.TEST, "skip sending email in test mode")
_test_logger.info("skip sending email in test mode")
return message['Message-Id']
# Get SMTP Server Details from Mail Server

View File

@ -26,7 +26,7 @@ import types
import openerp
from openerp import SUPERUSER_ID
from openerp import netsvc, pooler, tools
from openerp import tools
from openerp.osv import fields,osv
from openerp.osv.orm import Model
from openerp.tools.safe_eval import safe_eval as eval
@ -50,7 +50,7 @@ def _get_fields_type(self, cr, uid, context=None):
def _in_modules(self, cr, uid, ids, field_name, arg, context=None):
#pseudo-method used by fields.function in ir.model/ir.model.fields
module_pool = self.pool.get("ir.module.module")
module_pool = self.pool["ir.module.module"]
installed_module_ids = module_pool.search(cr, uid, [('state','=','installed')])
installed_module_names = module_pool.read(cr, uid, installed_module_ids, ['name'], context=context)
installed_modules = set(x['name'] for x in installed_module_names)
@ -71,7 +71,7 @@ class ir_model(osv.osv):
res = dict.fromkeys(ids)
for model in models:
if self.pool.get(model.model):
res[model.id] = self.pool.get(model.model).is_transient()
res[model.id] = self.pool[model.model].is_transient()
else:
_logger.error('Missing model %s' % (model.model, ))
return res
@ -91,7 +91,7 @@ class ir_model(osv.osv):
models = self.browse(cr, uid, ids)
res = {}
for model in models:
res[model.id] = self.pool.get("ir.ui.view").search(cr, uid, [('model', '=', model.model)])
res[model.id] = self.pool["ir.ui.view"].search(cr, uid, [('model', '=', model.model)])
return res
_columns = {
@ -144,7 +144,7 @@ class ir_model(osv.osv):
def _drop_table(self, cr, uid, ids, context=None):
for model in self.browse(cr, uid, ids, context):
model_pool = self.pool.get(model.model)
model_pool = self.pool[model.model]
cr.execute('select relkind from pg_class where relname=%s', (model_pool._table,))
result = cr.fetchone()
if result and result[0] == 'v':
@ -168,7 +168,7 @@ class ir_model(osv.osv):
if not context.get(MODULE_UNINSTALL_FLAG):
# only reload pool for normal unlink. For module uninstall the
# reload is done independently in openerp.modules.loading
pooler.restart_pool(cr.dbname)
openerp.modules.registry.RegistryManager.new(cr.dbname)
return res
@ -193,8 +193,7 @@ class ir_model(osv.osv):
field_name=vals['name'],
field_state='manual',
select=vals.get('select_level', '0'))
self.pool.get(vals['model'])._auto_init(cr, ctx)
#pooler.restart_pool(cr.dbname)
self.pool[vals['model']]._auto_init(cr, ctx)
return res
def instanciate(self, cr, user, model, context=None):
@ -298,7 +297,7 @@ class ir_model_fields(osv.osv):
def _drop_column(self, cr, uid, ids, context=None):
for field in self.browse(cr, uid, ids, context):
model = self.pool.get(field.model)
model = self.pool[field.model]
cr.execute('select relkind from pg_class where relname=%s', (model._table,))
result = cr.fetchone()
cr.execute("SELECT column_name FROM information_schema.columns WHERE table_name ='%s' and column_name='%s'" %(model._table, field.name))
@ -323,7 +322,7 @@ class ir_model_fields(osv.osv):
def create(self, cr, user, vals, context=None):
if 'model_id' in vals:
model_data = self.pool.get('ir.model').browse(cr, user, vals['model_id'])
model_data = self.pool['ir.model'].browse(cr, user, vals['model_id'])
vals['model'] = model_data.model
if context is None:
context = {}
@ -338,18 +337,18 @@ class ir_model_fields(osv.osv):
if not vals['name'].startswith('x_'):
raise except_orm(_('Error'), _("Custom fields must have a name that starts with 'x_' !"))
if vals.get('relation',False) and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]):
if vals.get('relation',False) and not self.pool['ir.model'].search(cr, user, [('model','=',vals['relation'])]):
raise except_orm(_('Error'), _("Model %s does not exist!") % vals['relation'])
if self.pool.get(vals['model']):
self.pool.get(vals['model']).__init__(self.pool, cr)
self.pool[vals['model']].__init__(self.pool, cr)
#Added context to _auto_init for special treatment to custom field for select_level
ctx = dict(context,
field_name=vals['name'],
field_state='manual',
select=vals.get('select_level', '0'),
update_custom_fields=True)
self.pool.get(vals['model'])._auto_init(cr, ctx)
self.pool[vals['model']]._auto_init(cr, ctx)
return res
@ -498,7 +497,7 @@ class ir_model_constraint(Model):
Delete PostgreSQL foreign keys and constraints tracked by this model.
"""
if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
context = dict(context or {})
@ -559,7 +558,7 @@ class ir_model_relation(Model):
Delete PostgreSQL many2many relations tracked by this model.
"""
if uid != SUPERUSER_ID and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
if uid != SUPERUSER_ID and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
ids_set = set(ids)
@ -685,7 +684,7 @@ class ir_model_access(osv.osv):
# TransientModel records have no access rights, only an implicit access rule
if not self.pool.get(model_name):
_logger.error('Missing model %s' % (model_name, ))
elif self.pool.get(model_name).is_transient():
elif self.pool[model_name].is_transient():
return True
# We check if a specific rule exists
@ -793,7 +792,7 @@ class ir_model_data(osv.osv):
for model in result:
try:
r = dict(self.pool.get(model).name_get(cr, uid, result[model].keys(), context=context))
r = dict(self.pool[model].name_get(cr, uid, result[model].keys(), context=context))
for key,val in result[model].items():
result2[val] = r.get(key, False)
except:
@ -867,7 +866,7 @@ class ir_model_data(osv.osv):
def get_object(self, cr, uid, module, xml_id, context=None):
"""Returns a browsable record for the given module name and xml_id or raise ValueError if not found"""
res_model, res_id = self.get_object_reference(cr, uid, module, xml_id)
result = self.pool.get(res_model).browse(cr, uid, res_id, context=context)
result = self.pool[res_model].browse(cr, uid, res_id, context=context)
if not result.exists():
raise ValueError('No record found for unique ID %s.%s. It may have been deleted.' % (module, xml_id))
return result
@ -1001,7 +1000,7 @@ class ir_model_data(osv.osv):
cr.execute('select * from ir_values where model=%s and key=%s and name=%s'+where,(model, key, name))
res = cr.fetchone()
if not res:
ir_values_obj = pooler.get_pool(cr.dbname).get('ir.values')
ir_values_obj = openerp.registry(cr.dbname)['ir.values']
ir_values_obj.set(cr, uid, key, key2, name, models, value, replace, isobject, meta)
elif xml_id:
cr.execute('UPDATE ir_values set value=%s WHERE model=%s and key=%s and name=%s'+where,(value, model, key, name))
@ -1020,7 +1019,7 @@ class ir_model_data(osv.osv):
ids = self.search(cr, uid, [('module', 'in', modules_to_remove)])
if uid != 1 and not self.pool.get('ir.model.access').check_groups(cr, uid, "base.group_system"):
if uid != 1 and not self.pool['ir.model.access'].check_groups(cr, uid, "base.group_system"):
raise except_orm(_('Permission Denied'), (_('Administrator access is required to uninstall a module')))
context = dict(context or {})
@ -1047,10 +1046,9 @@ class ir_model_data(osv.osv):
wkf_todo.extend(cr.fetchall())
cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id))
wf_service = netsvc.LocalService("workflow")
for model,res_id in wkf_todo:
try:
wf_service.trg_write(uid, model, res_id, cr)
openerp.workflow.trg_write(uid, model, res_id, cr)
except Exception:
_logger.info('Unable to force processing of workflow for item %s@%s in order to leave activity to be deleted', res_id, model, exc_info=True)
@ -1063,7 +1061,7 @@ class ir_model_data(osv.osv):
if model == 'ir.model.fields':
# Don't remove the LOG_ACCESS_COLUMNS unless _log_access
# has been turned off on the model.
field = self.pool.get(model).browse(cr, uid, [res_id], context=context)[0]
field = self.pool[model].browse(cr, uid, [res_id], context=context)[0]
if field.name in openerp.osv.orm.LOG_ACCESS_COLUMNS and self.pool[field.model]._log_access:
continue
if field.name == 'id':
@ -1071,7 +1069,7 @@ class ir_model_data(osv.osv):
_logger.info('Deleting %s@%s', res_id, model)
try:
cr.execute('SAVEPOINT record_unlink_save')
self.pool.get(model).unlink(cr, uid, [res_id], context=context)
self.pool[model].unlink(cr, uid, [res_id], context=context)
except Exception:
_logger.info('Unable to delete %s@%s', res_id, model, exc_info=True)
cr.execute('ROLLBACK TO SAVEPOINT record_unlink_save')
@ -1084,8 +1082,8 @@ class ir_model_data(osv.osv):
unlink_if_refcount((model, res_id) for model, res_id in to_unlink
if model == 'ir.model.fields')
ir_model_relation = self.pool.get('ir.model.relation')
ir_module_module = self.pool.get('ir.module.module')
ir_model_relation = self.pool['ir.model.relation']
ir_module_module = self.pool['ir.module.module']
modules_to_remove_ids = ir_module_module.search(cr, uid, [('name', 'in', modules_to_remove)])
relation_ids = ir_model_relation.search(cr, uid, [('module', 'in', modules_to_remove_ids)])
ir_model_relation._module_data_uninstall(cr, uid, relation_ids, context)
@ -1118,6 +1116,6 @@ class ir_model_data(osv.osv):
for (model, res_id) in to_unlink:
if self.pool.get(model):
_logger.info('Deleting %s@%s', res_id, model)
self.pool.get(model).unlink(cr, uid, [res_id])
self.pool[model].unlink(cr, uid, [res_id])
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -21,7 +21,7 @@
from openerp.osv import fields, osv
from openerp.tools.translate import _
from openerp import netsvc
import openerp.workflow
class workflow(osv.osv):
_name = "workflow"
@ -40,8 +40,7 @@ class workflow(osv.osv):
def write(self, cr, user, ids, vals, context=None):
if not context:
context={}
wf_service = netsvc.LocalService("workflow")
wf_service.clear_cache(cr, user)
openerp.workflow.clear_cache(cr, user)
return super(workflow, self).write(cr, user, ids, vals, context=context)
def get_active_workitems(self, cr, uid, res, res_id, context=None):
@ -62,8 +61,7 @@ class workflow(osv.osv):
def create(self, cr, user, vals, context=None):
if not context:
context={}
wf_service = netsvc.LocalService("workflow")
wf_service.clear_cache(cr, user)
openerp.workflow.clear_cache(cr, user)
return super(workflow, self).create(cr, user, vals, context=context)
workflow()

View File

@ -39,7 +39,7 @@ except ImportError:
from StringIO import StringIO # NOQA
import openerp
from openerp import modules, pooler, tools, addons
from openerp import modules, tools, addons
from openerp.modules.db import create_categories
from openerp.tools.parse_version import parse_version
from openerp.tools.translate import _
@ -473,14 +473,14 @@ class module(osv.osv):
function(cr, uid, ids, context=context)
cr.commit()
_, pool = pooler.restart_pool(cr.dbname, update_module=True)
registry = openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True)
config = pool.get('res.config').next(cr, uid, [], context=context) or {}
config = registry['res.config'].next(cr, uid, [], context=context) or {}
if config.get('type') not in ('ir.actions.act_window_close',):
return config
# reload the client; open the first available root menu
menu_obj = self.pool.get('ir.ui.menu')
menu_obj = registry['ir.ui.menu']
menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
return {
'type': 'ir.actions.client',

View File

@ -19,7 +19,7 @@
#
##############################################################################
from openerp import pooler
import openerp
from openerp.osv import osv, fields
from openerp.tools.translate import _
@ -87,7 +87,7 @@ class base_module_upgrade(osv.osv_memory):
ir_module.download(cr, uid, ids, context=context)
cr.commit() # save before re-creating cursor below
pooler.restart_pool(cr.dbname, update_module=True)
openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True)
ir_model_data = self.pool.get('ir.model.data')
__, res_id = ir_model_data.get_object_reference(cr, uid, 'base', 'view_base_module_upgrade_install')

View File

@ -23,7 +23,7 @@ from operator import attrgetter
import re
import openerp
from openerp import pooler, SUPERUSER_ID
from openerp import SUPERUSER_ID
from openerp.osv import osv, fields
from openerp.tools import ustr
from openerp.tools.translate import _
@ -72,7 +72,7 @@ class res_config_configurable(osv.osv_memory):
res['nodestroy'] = False
return res
# reload the client; open the first available root menu
menu_obj = self.pool.get('ir.ui.menu')
menu_obj = self.pool['ir.ui.menu']
menu_ids = menu_obj.search(cr, uid, [('parent_id', '=', False)], context=context)
return {
'type': 'ir.actions.client',
@ -271,7 +271,7 @@ class res_config_installer(osv.osv_memory):
:returns: a list of all installed modules in this installer
:rtype: [browse_record]
"""
modules = self.pool.get('ir.module.module')
modules = self.pool['ir.module.module']
selectable = [field for field in self._columns
if type(self._columns[field]) is fields.boolean]
@ -353,7 +353,7 @@ class res_config_installer(osv.osv_memory):
return fields
def execute(self, cr, uid, ids, context=None):
modules = self.pool.get('ir.module.module')
modules = self.pool['ir.module.module']
to_install = list(self.modules_to_install(
cr, uid, ids, context=context))
_logger.info('Selecting addons %s to install', to_install)
@ -363,7 +363,7 @@ class res_config_installer(osv.osv_memory):
'to install', ['uninstalled'], context=context)
cr.commit()
openerp.modules.registry.RegistryManager.signal_registry_change(cr.dbname)
new_db, self.pool = pooler.restart_pool(cr.dbname, update_module=True)
openerp.modules.registry.RegistryManager.new(cr.dbname, update_module=True)
res_config_installer()
@ -455,8 +455,8 @@ class res_config_settings(osv.osv_memory):
'other': ['other_field', ...],
}
"""
ir_model_data = self.pool.get('ir.model.data')
ir_module = self.pool.get('ir.module.module')
ir_model_data = self.pool['ir.model.data']
ir_module = self.pool['ir.module.module']
def ref(xml_id):
mod, xml = xml_id.split('.', 1)
return ir_model_data.get_object(cr, uid, mod, xml, context)
@ -478,7 +478,7 @@ class res_config_settings(osv.osv_memory):
return {'default': defaults, 'group': groups, 'module': modules, 'other': others}
def default_get(self, cr, uid, fields, context=None):
ir_values = self.pool.get('ir.values')
ir_values = self.pool['ir.values']
classified = self._get_classified_fields(cr, uid, context)
res = super(res_config_settings, self).default_get(cr, uid, fields, context)
@ -505,8 +505,8 @@ class res_config_settings(osv.osv_memory):
return res
def execute(self, cr, uid, ids, context=None):
ir_values = self.pool.get('ir.values')
ir_module = self.pool.get('ir.module.module')
ir_values = self.pool['ir.values']
ir_module = self.pool['ir.module.module']
classified = self._get_classified_fields(cr, uid, context)
config = self.browse(cr, uid, ids[0], context)
@ -572,7 +572,7 @@ class res_config_settings(osv.osv_memory):
def cancel(self, cr, uid, ids, context=None):
# ignore the current record, and send the action to reopen the view
act_window = self.pool.get('ir.actions.act_window')
act_window = self.pool['ir.actions.act_window']
action_ids = act_window.search(cr, uid, [('res_model', '=', self._name)])
if action_ids:
return act_window.read(cr, uid, action_ids[0], [], context=context)
@ -588,7 +588,7 @@ class res_config_settings(osv.osv_memory):
if isinstance(ids, (int, long)):
ids = [ids]
act_window = self.pool.get('ir.actions.act_window')
act_window = self.pool['ir.actions.act_window']
action_ids = act_window.search(cr, uid, [('res_model', '=', self._name)], context=context)
name = self._name
if action_ids:
@ -606,8 +606,8 @@ class res_config_settings(osv.osv_memory):
- t[1]: long: id of the menuitem's action
"""
module_name, menu_xml_id = menu_xml_id.split('.')
dummy, menu_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, module_name, menu_xml_id)
ir_ui_menu = self.pool.get('ir.ui.menu').browse(cr, uid, menu_id, context=context)
dummy, menu_id = self.pool['ir.model.data'].get_object_reference(cr, uid, module_name, menu_xml_id)
ir_ui_menu = self.pool['ir.ui.menu'].browse(cr, uid, menu_id, context=context)
return (ir_ui_menu.complete_name, ir_ui_menu.action.id)
@ -621,7 +621,7 @@ class res_config_settings(osv.osv_memory):
"""
model_name, field_name = full_field_name.rsplit('.', 1)
return self.pool.get(model_name).fields_get(cr, uid, allfields=[field_name], context=context)[field_name]['string']
return self.pool[model_name].fields_get(cr, uid, allfields=[field_name], context=context)[field_name]['string']
def get_config_warning(self, cr, msg, context=None):
"""
@ -652,7 +652,7 @@ class res_config_settings(osv.osv_memory):
Cannot find any account journal of %s type for this company.\n\nYou can create one in the %%(menu:account.menu_account_config)s.
"""
res_config_obj = pooler.get_pool(cr.dbname).get('res.config.settings')
res_config_obj = openerp.registry(cr.dbname)['res.config.settings']
regex_path = r'%\(((?:menu|field):[a-z_\.]*)\)s'
# Process the message

View File

@ -27,13 +27,13 @@ import re
import openerp
from openerp import SUPERUSER_ID
from openerp import pooler, tools
from openerp import tools
from openerp.osv import osv, fields
from openerp.tools.translate import _
class format_address(object):
def fields_view_get_address(self, cr, uid, arch, context={}):
user_obj = self.pool.get('res.users')
user_obj = self.pool['res.users']
fmt = user_obj.browse(cr, SUPERUSER_ID, uid, context).company_id.country_id
fmt = fmt and fmt.address_format
layouts = {
@ -154,7 +154,7 @@ class res_partner_title(osv.osv):
}
def _lang_get(self, cr, uid, context=None):
lang_pool = self.pool.get('res.lang')
lang_pool = self.pool['res.lang']
ids = lang_pool.search(cr, uid, [], context=context)
res = lang_pool.read(cr, uid, ids, ['code', 'name'], context)
return [(r['code'], r['name']) for r in res]
@ -294,7 +294,7 @@ class res_partner(osv.osv, format_address):
def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):
if (not view_id) and (view_type=='form') and context and context.get('force_email', False):
view_id = self.pool.get('ir.model.data').get_object_reference(cr, user, 'base', 'view_partner_simple_form')[1]
view_id = self.pool['ir.model.data'].get_object_reference(cr, user, 'base', 'view_partner_simple_form')[1]
res = super(res_partner,self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu)
if view_type == 'form':
res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context)
@ -306,7 +306,7 @@ class res_partner(osv.osv, format_address):
'tz': lambda self, cr, uid, ctx: ctx.get('tz', False),
'customer': True,
'category_id': _default_category,
'company_id': lambda self, cr, uid, ctx: self.pool.get('res.company')._company_default_get(cr, uid, 'res.partner', context=ctx),
'company_id': lambda self, cr, uid, ctx: self.pool['res.company']._company_default_get(cr, uid, 'res.partner', context=ctx),
'color': 0,
'is_company': False,
'type': 'default',
@ -343,12 +343,12 @@ class res_partner(osv.osv, format_address):
def onchange_state(self, cr, uid, ids, state_id, context=None):
if state_id:
country_id = self.pool.get('res.country.state').browse(cr, uid, state_id, context).country_id.id
country_id = self.pool['res.country.state'].browse(cr, uid, state_id, context).country_id.id
return {'value':{'country_id':country_id}}
return {}
def _check_ean_key(self, cr, uid, ids, context=None):
for partner_o in pooler.get_pool(cr.dbname).get('res.partner').read(cr, uid, ids, ['ean13',]):
for partner_o in self.pool['res.partner'].read(cr, uid, ids, ['ean13',]):
thisean=partner_o['ean13']
if thisean and thisean!='':
if len(thisean)!=13:
@ -498,7 +498,7 @@ class res_partner(osv.osv, format_address):
def email_send(self, cr, uid, ids, email_from, subject, body, on_error=''):
while len(ids):
self.pool.get('ir.cron').create(cr, uid, {
self.pool['ir.cron'].create(cr, uid, {
'name': 'Send Partner Emails',
'user_id': uid,
'model': 'res.partner',
@ -534,12 +534,12 @@ class res_partner(osv.osv, format_address):
if res: return res
if not context.get('category_id', False):
return False
return _('Partners: ')+self.pool.get('res.partner.category').browse(cr, uid, context['category_id'], context).name
return _('Partners: ')+self.pool['res.partner.category'].browse(cr, uid, context['category_id'], context).name
def main_partner(self, cr, uid):
''' Return the id of the main partner
'''
model_data = self.pool.get('ir.model.data')
model_data = self.pool['ir.model.data']
return model_data.browse(cr, uid,
model_data.search(cr, uid, [('module','=','base'),
('name','=','main_partner')])[0],

View File

@ -26,7 +26,7 @@ from lxml.builder import E
import openerp
from openerp import SUPERUSER_ID
from openerp import pooler, tools
from openerp import tools
import openerp.exceptions
from openerp.osv import fields,osv
from openerp.osv.orm import browse_record
@ -98,7 +98,7 @@ class groups(osv.osv):
raise osv.except_osv(_('Error'),
_('The name of the group can not start with "-"'))
res = super(groups, self).write(cr, uid, ids, vals, context=context)
self.pool.get('ir.model.access').call_cache_clearing_methods(cr)
self.pool['ir.model.access'].call_cache_clearing_methods(cr)
return res
groups()
@ -181,7 +181,7 @@ class res_users(osv.osv):
partner.onchange_type method, but applied to the user object.
"""
partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context=context)]
return self.pool.get('res.partner').onchange_type(cr, uid, partner_ids, is_company, context=context)
return self.pool['res.partner'].onchange_type(cr, uid, partner_ids, is_company, context=context)
def onchange_address(self, cr, uid, ids, use_parent_address, parent_id, context=None):
""" Wrapper on the user.partner onchange_address, because some calls to the
@ -189,7 +189,7 @@ class res_users(osv.osv):
partner.onchange_type method, but applied to the user object.
"""
partner_ids = [user.partner_id.id for user in self.browse(cr, uid, ids, context=context)]
return self.pool.get('res.partner').onchange_address(cr, uid, partner_ids, use_parent_address, parent_id, context=context)
return self.pool['res.partner'].onchange_address(cr, uid, partner_ids, use_parent_address, parent_id, context=context)
def _check_company(self, cr, uid, ids, context=None):
return all(((this.company_id in this.company_ids) or not this.company_ids) for this in self.browse(cr, uid, ids, context))
@ -205,7 +205,7 @@ class res_users(osv.osv):
def _get_company(self,cr, uid, context=None, uid2=False):
if not uid2:
uid2 = uid
user = self.pool.get('res.users').read(cr, uid, uid2, ['company_id'], context)
user = self.pool['res.users'].read(cr, uid, uid2, ['company_id'], context)
company_id = user.get('company_id', False)
return company_id and company_id[0] or False
@ -246,7 +246,7 @@ class res_users(osv.osv):
'company_id': _get_company,
'company_ids': _get_companies,
'groups_id': _get_group,
'image': lambda self, cr, uid, ctx={}: self.pool.get('res.partner')._get_default_image(cr, uid, False, ctx, colorize=True),
'image': lambda self, cr, uid, ctx={}: self.pool['res.partner']._get_default_image(cr, uid, False, ctx, colorize=True),
}
# User can write on a few of his own fields (but not his groups for example)
@ -275,7 +275,7 @@ class res_users(osv.osv):
uid = SUPERUSER_ID
result = super(res_users, self).read(cr, uid, ids, fields=fields, context=context, load=load)
canwrite = self.pool.get('ir.model.access').check(cr, uid, 'res.users', 'write', False)
canwrite = self.pool['ir.model.access'].check(cr, uid, 'res.users', 'write', False)
if not canwrite:
if isinstance(ids, (int, long)):
result = override_password(result)
@ -300,8 +300,8 @@ class res_users(osv.osv):
res = super(res_users, self).write(cr, uid, ids, values, context=context)
# clear caches linked to the users
self.pool.get('ir.model.access').call_cache_clearing_methods(cr)
clear = partial(self.pool.get('ir.rule').clear_cache, cr)
self.pool['ir.model.access'].call_cache_clearing_methods(cr)
clear = partial(self.pool['ir.rule'].clear_cache, cr)
map(clear, ids)
db = cr.dbname
if db in self._uid_cache:
@ -361,7 +361,7 @@ class res_users(osv.osv):
return result
def action_get(self, cr, uid, context=None):
dataobj = self.pool.get('ir.model.data')
dataobj = self.pool['ir.model.data']
data_id = dataobj._get_id(cr, SUPERUSER_ID, 'base', 'action_res_users_my')
return dataobj.browse(cr, uid, data_id, context=context).res_id
@ -381,7 +381,7 @@ class res_users(osv.osv):
if not password:
return False
user_id = False
cr = pooler.get_db(db).cursor()
cr = self.pool.db.cursor()
try:
# autocommit: our single update request will be performed atomically.
# (In this way, there is no opportunity to have two transactions
@ -432,10 +432,10 @@ class res_users(osv.osv):
# Successfully logged in as admin!
# Attempt to guess the web base url...
if user_agent_env and user_agent_env.get('base_location'):
cr = pooler.get_db(db).cursor()
cr = self.pool.db.cursor()
try:
base = user_agent_env['base_location']
self.pool.get('ir.config_parameter').set_param(cr, uid, 'web.base.url', base)
self.pool['ir.config_parameter'].set_param(cr, uid, 'web.base.url', base)
cr.commit()
except Exception:
_logger.exception("Failed to update web.base.url configuration parameter")
@ -451,7 +451,7 @@ class res_users(osv.osv):
raise openerp.exceptions.AccessDenied()
if self._uid_cache.get(db, {}).get(uid) == passwd:
return
cr = pooler.get_db(db).cursor()
cr = self.pool.db.cursor()
try:
self.check_credentials(cr, uid, passwd)
if self._uid_cache.has_key(db):
@ -699,7 +699,7 @@ class groups_view(osv.osv):
def get_user_groups_view(self, cr, uid, context=None):
try:
view = self.pool.get('ir.model.data').get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context)
view = self.pool['ir.model.data'].get_object(cr, SUPERUSER_ID, 'base', 'user_groups_view', context)
assert view and view._table_name == 'ir.ui.view'
except Exception:
view = False
@ -835,7 +835,7 @@ class users_view(osv.osv):
def fields_get(self, cr, uid, allfields=None, context=None, write_access=True):
res = super(users_view, self).fields_get(cr, uid, allfields, context, write_access)
# add reified groups fields
for app, kind, gs in self.pool.get('res.groups').get_groups_by_application(cr, uid, context):
for app, kind, gs in self.pool['res.groups'].get_groups_by_application(cr, uid, context):
if kind == 'selection':
# selection group field
tips = ['%s: %s' % (g.name, g.comment) for g in gs if g.comment]

View File

@ -95,7 +95,7 @@ def preload_registry(dbname):
""" Preload a registry, and start the cron."""
try:
update_module = True if openerp.tools.config['init'] or openerp.tools.config['update'] else False
db, registry = openerp.pooler.get_db_and_pool(dbname,update_module=update_module)
openerp.modules.registry.RegistryManager.new(dbname, update_module=update_module)
except Exception:
_logger.exception('Failed to initialize database `%s`.', dbname)
@ -103,8 +103,8 @@ def run_test_file(dbname, test_file):
""" Preload a registry, possibly run a test file, and start the cron."""
try:
config = openerp.tools.config
db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'])
cr = db.cursor()
registry = openerp.modules.registry.RegistryManager.new(dbname, update_module=config['init'] or config['update'])
cr = registry.db.cursor()
_logger.info('loading test file %s', test_file)
openerp.tools.convert_yaml_import(cr, 'base', file(test_file), 'test', {}, 'test', True)
cr.rollback()
@ -125,7 +125,8 @@ def export_translation():
fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
buf = file(config["translate_out"], "w")
cr = openerp.pooler.get_db(dbname).cursor()
registry = openerp.modules.registry.RegistryManager.new(dbname)
cr = registry.db.cursor()
openerp.tools.trans_export(config["language"],
config["translate_modules"] or ["all"], buf, fileformat, cr)
cr.close()
@ -138,7 +139,8 @@ def import_translation():
context = {'overwrite': config["overwrite_existing_translations"]}
dbname = config['db_name']
cr = openerp.pooler.get_db(dbname).cursor()
registry = openerp.modules.registry.RegistryManager.new(dbname)
cr = registry.db.cursor()
openerp.tools.trans_load( cr, config["translate_in"], config["language"],
context=context)
cr.commit()

View File

@ -26,6 +26,8 @@ additional code is needed throughout the core library. This module keeps
track of those specific measures by providing variables that can be unset
by the user to check if her code is future proof.
In a perfect world, all these variables are set to False, the corresponding
code removed, and thus these variables made unnecessary.
"""
# If True, the Python modules inside the openerp namespace are made available
@ -35,4 +37,25 @@ by the user to check if her code is future proof.
# Change to False around 2013.02.
open_openerp_namespace = False
# If True, openerp.netsvc.LocalService() can be used to lookup reports or to
# access openerp.workflow.
# Introduced around 2013.03.
# Among the related code:
# - The openerp.netsvc.LocalService() function.
# - The openerp.report.interface.report_int._reports dictionary.
# - The register attribute in openerp.report.interface.report_int (and in its
# - auto column in ir.actions.report.xml.
# inheriting classes).
allow_local_service = True
# Applies for the register attribute in openerp.report.interface.report_int.
# See comments for allow_local_service above.
# Introduced around 2013.03.
allow_report_int_registration = True
# If True, the functions in openerp.pooler can be used.
# Introduced around 2013.03 (actually they are deprecated since much longer
# but no warning was dispayed in the logs).
openerp_pooler = True
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -107,6 +107,7 @@
<rng:optional><rng:attribute name="sxw"/></rng:optional>
<rng:optional><rng:attribute name="xml"/></rng:optional>
<rng:optional><rng:attribute name="xsl"/></rng:optional>
<rng:optional><rng:attribute name="parser"/></rng:optional>
<rng:optional> <rng:attribute name="auto" /> </rng:optional>
<rng:optional> <rng:attribute name="header" /> </rng:optional>
<rng:optional> <rng:attribute name="webkit_header" /> </rng:optional>

View File

@ -20,80 +20,14 @@
##############################################################################
import sys
import logging
LOG_NOTSET = 'notset'
LOG_DEBUG = 'debug'
LOG_TEST = 'test'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'
logging.TEST = logging.INFO - 5
logging.addLevelName(logging.TEST, 'TEST')
_logger = logging.getLogger(__name__)
class Logger(object):
def __init__(self):
_logger.warning(
"The netsvc.Logger API shouldn't be used anymore, please "
"use the standard `logging.getLogger` API instead.")
super(Logger, self).__init__()
def notifyChannel(self, name, level, msg):
_logger.warning(
"notifyChannel API shouldn't be used anymore, please use "
"the standard `logging` module instead.")
from service import common
log = logging.getLogger(__name__ + '.deprecated.' + ustr(name))
if level in [LOG_TEST] and not hasattr(log, level):
fct = lambda msg, *args, **kwargs: log.log(getattr(logging, level.upper()), msg, *args, **kwargs)
setattr(log, level, fct)
level_method = getattr(log, level)
if isinstance(msg, Exception):
msg = exception_to_unicode(msg)
try:
msg = ustr(msg).strip()
if level in (LOG_ERROR, LOG_CRITICAL): # and tools.config.get_misc('debug','env_info',False):
msg = common.exp_get_server_environment() + "\n" + msg
result = msg.split('\n')
except UnicodeDecodeError:
result = msg.strip().split('\n')
try:
if len(result)>1:
for idx, s in enumerate(result):
level_method('[%02d]: %s' % (idx+1, s,))
elif result:
level_method(result[0])
except IOError:
# TODO: perhaps reset the logger streams?
#if logrotate closes our files, we end up here..
pass
except Exception:
# better ignore the exception and carry on..
pass
def set_loglevel(self, level, logger=None):
if logger is not None:
log = logging.getLogger(str(logger))
else:
log = logging.getLogger()
log.setLevel(logging.INFO) # make sure next msg is printed
log.info("Log level changed to %s" % logging.getLevelName(level))
log.setLevel(level)
def shutdown(self):
logging.shutdown()
# TODO get_encodings, ustr and exception_to_unicode were originally from tools.misc.
# There are here until we refactor tools so that this module doesn't depends on tools.

View File

@ -33,11 +33,8 @@ import openerp.osv as osv
import openerp.tools as tools
import openerp.tools.osutil as osutil
from openerp.tools.safe_eval import safe_eval as eval
import openerp.pooler as pooler
from openerp.tools.translate import _
import openerp.netsvc as netsvc
import zipfile
import openerp.release as release

View File

@ -35,7 +35,6 @@ import openerp.modules.db
import openerp.modules.graph
import openerp.modules.migration
import openerp.osv as osv
import openerp.pooler as pooler
import openerp.tools as tools
from openerp import SUPERUSER_ID
@ -44,6 +43,7 @@ from openerp.modules.module import initialize_sys_path, \
load_openerp_module, init_module_models, adapt_version
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=None, report=None):
@ -75,7 +75,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
_load_data(cr, module_name, idref, mode, 'test')
return True
except Exception:
_logger.exception(
_test_logger.exception(
'module %s: an exception occurred in a test', module_name)
return False
finally:
@ -96,7 +96,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
"""
for filename in package.data[kind]:
if kind == 'test':
_logger.log(logging.TEST, "module %s: loading %s", module_name, filename)
_test_logger.info("module %s: loading %s", module_name, filename)
else:
_logger.info("module %s: loading %s", module_name, filename)
_, ext = os.path.splitext(filename)
@ -129,17 +129,17 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
processed_modules = []
loaded_modules = []
pool = pooler.get_pool(cr.dbname)
registry = openerp.registry(cr.dbname)
migrations = openerp.modules.migration.MigrationManager(cr, graph)
_logger.debug('loading %d packages...', len(graph))
# Query manual fields for all models at once and save them on the registry
# so the initialization code for each model does not have to do it
# one model at a time.
pool.fields_by_model = {}
registry.fields_by_model = {}
cr.execute('SELECT * FROM ir_model_fields WHERE state=%s', ('manual',))
for field in cr.dictfetchall():
pool.fields_by_model.setdefault(field['model'], []).append(field)
registry.fields_by_model.setdefault(field['model'], []).append(field)
# register, instantiate and initialize models for each modules
for index, package in enumerate(graph):
@ -153,17 +153,17 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
migrations.migrate_module(package, 'pre')
load_openerp_module(package.name)
models = pool.load(cr, package)
models = registry.load(cr, package)
loaded_modules.append(package.name)
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
init_module_models(cr, package.name, models)
pool._init_modules.add(package.name)
registry._init_modules.add(package.name)
status['progress'] = float(index) / len(graph)
# Can't put this line out of the loop: ir.module.module will be
# registered by init_module_models() above.
modobj = pool.get('ir.module.module')
modobj = registry['ir.module.module']
if perform_checks:
modobj.check(cr, SUPERUSER_ID, [module_id])
@ -219,7 +219,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
# The query won't be valid for models created later (i.e. custom model
# created after the registry has been loaded), so empty its result.
pool.fields_by_model = None
registry.fields_by_model = None
cr.commit()
@ -258,7 +258,7 @@ def load_marked_modules(cr, graph, states, force, progressdict, report, loaded_m
def load_modules(db, force_demo=False, status=None, update_module=False):
# TODO status['progress'] reporting is broken: used twice (and reset each
# time to zero) in load_module_graph, not fine-grained enough.
# It should be a method exposed by the pool.
# It should be a method exposed by the registry.
initialize_sys_path()
force = []
@ -275,8 +275,9 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
if not tools.config['without_demo']:
tools.config["demo"]['all'] = 1
# This is a brand new pool, just created in pooler.get_db_and_pool()
pool = pooler.get_pool(cr.dbname)
# This is a brand new registry, just created in
# openerp.modules.registry.RegistryManger.new().
registry = openerp.registry(cr.dbname)
if 'base' in tools.config['update'] or 'all' in tools.config['update']:
cr.execute("update ir_module_module set state=%s where name=%s and state=%s", ('to upgrade', 'base', 'installed'))
@ -290,7 +291,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# processed_modules: for cleanup step after install
# loaded_modules: to avoid double loading
report = pool._assertion_report
report = registry._assertion_report
loaded_modules, processed_modules = load_module_graph(cr, graph, status, perform_checks=update_module, report=report)
if tools.config['load_language']:
@ -299,7 +300,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# STEP 2: Mark other modules to be loaded/updated
if update_module:
modobj = pool.get('ir.module.module')
modobj = registry['ir.module.module']
if ('base' in tools.config['init']) or ('base' in tools.config['update']):
_logger.info('updating modules list')
modobj.update_list(cr, SUPERUSER_ID)
@ -341,13 +342,13 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# load custom models
cr.execute('select model from ir_model where state=%s', ('manual',))
for model in cr.dictfetchall():
pool.get('ir.model').instanciate(cr, SUPERUSER_ID, model['model'], {})
registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {})
# STEP 4: Finish and cleanup installations
if processed_modules:
cr.execute("""select model,name from ir_model where id NOT IN (select distinct model_id from ir_model_access)""")
for (model, name) in cr.fetchall():
model_obj = pool.get(model)
model_obj = registry.get(model)
if model_obj and not model_obj.is_transient():
_logger.warning('The model %s has no access rules, consider adding one. E.g. access_%s,access_%s,model_%s,,1,1,1,1',
model, model.replace('.', '_'), model.replace('.', '_'), model.replace('.', '_'))
@ -356,20 +357,20 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
# been replaced by owner-only access rights
cr.execute("""select distinct mod.model, mod.name from ir_model_access acc, ir_model mod where acc.model_id = mod.id""")
for (model, name) in cr.fetchall():
model_obj = pool.get(model)
model_obj = registry.get(model)
if model_obj and model_obj.is_transient():
_logger.warning('The transient model %s (%s) should not have explicit access rules!', model, name)
cr.execute("SELECT model from ir_model")
for (model,) in cr.fetchall():
obj = pool.get(model)
obj = registry.get(model)
if obj:
obj._check_removed_columns(cr, log=True)
else:
_logger.warning("Model %s is declared but cannot be loaded! (Perhaps a module was partially removed or renamed)", model)
# Cleanup orphan records
pool.get('ir.model.data')._process_end(cr, SUPERUSER_ID, processed_modules)
registry['ir.model.data']._process_end(cr, SUPERUSER_ID, processed_modules)
for kind in ('init', 'demo', 'update'):
tools.config[kind] = {}
@ -403,12 +404,12 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
cr.execute("SELECT id FROM ir_module_module WHERE state=%s", ('to remove',))
mod_ids_to_remove = [x[0] for x in cr.fetchall()]
if mod_ids_to_remove:
pool.get('ir.module.module').module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove)
registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove)
# Recursive reload, should only happen once, because there should be no
# modules to remove next time
cr.commit()
_logger.info('Reloading registry once more after uninstalling modules')
return pooler.restart_pool(cr.dbname, force_demo, status, update_module)
return openerp.modules.registry.RegistryManger.new(cr.dbname, force_demo, status, update_module)
if report.failures:
_logger.error('At least one test failed when loading the modules.')
@ -416,7 +417,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
_logger.info('Modules loaded.')
# STEP 7: call _register_hook on every model
for model in pool.models.values():
for model in registry.models.values():
model._register_hook(cr)
finally:

View File

@ -33,11 +33,8 @@ import openerp.osv as osv
import openerp.tools as tools
import openerp.tools.osutil as osutil
from openerp.tools.safe_eval import safe_eval as eval
import openerp.pooler as pooler
from openerp.tools.translate import _
import openerp.netsvc as netsvc
import zipfile
import openerp.release as release

View File

@ -43,6 +43,7 @@ from cStringIO import StringIO
import logging
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
_ad = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'addons') # default addons path (base)
ad_paths = []
@ -503,7 +504,7 @@ def run_unit_tests(module_name):
for m in ms:
suite.addTests(unittest2.TestLoader().loadTestsFromModule(m))
if ms:
_logger.log(logging.TEST, 'module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms))
_test_logger.info('module %s: executing %s `fast_suite` and/or `checks` sub-modules', module_name, len(ms))
# Use a custom stream object to log the test executions.
class MyStream(object):
def __init__(self):
@ -518,7 +519,7 @@ def run_unit_tests(module_name):
if not first:
c = '` ' + c
first = False
_logger.log(logging.TEST, c)
_test_logger.info(c)
result = unittest2.TextTestRunner(verbosity=2, stream=MyStream()).run(suite)
if result.wasSuccessful():
return True

View File

@ -225,7 +225,6 @@ class RegistryManager(object):
try:
Registry.setup_multi_process_signaling(cr)
registry.do_parent_store(cr)
registry.get('ir.actions.report.xml').register_all(cr)
cr.commit()
finally:
cr.close()

View File

@ -21,37 +21,47 @@
##############################################################################
import errno
import logging
import logging.handlers
import os
import platform
import release
import sys
import threading
import time
import types
from pprint import pformat
import psutil
try:
import psutil
except ImportError:
psutil = None
# TODO modules that import netsvc only for things from loglevels must be changed to use loglevels.
from loglevels import *
import tools
import openerp
_logger = logging.getLogger(__name__)
def LocalService(name):
# Special case for addons support, will be removed in a few days when addons
# are updated to directly use openerp.osv.osv.service.
"""
The openerp.netsvc.LocalService() function is deprecated. It still works
in two cases: workflows and reports. For workflows, instead of using
LocalService('workflow'), openerp.workflow should be used (better yet,
methods on openerp.osv.orm.Model should be used). For reports,
openerp.report.render_report() should be used (methods on the Model should
be provided too in the future).
"""
assert openerp.conf.deprecation.allow_local_service
_logger.warning("LocalService() is deprecated since march 2013 (it was called with '%s')." % name)
if name == 'workflow':
return openerp.workflow
return openerp.report.interface.report_int._reports[name]
if name.startswith('report.'):
report = openerp.report.interface.report_int._reports.get(name)
if report:
return report
else:
dbname = getattr(threading.currentThread(), 'dbname', None)
if dbname:
registry = openerp.modules.registry.RegistryManager.get(dbname)
with registry.cursor() as cr:
return registry['ir.actions.report.xml']._lookup_report(cr, name[len('report.'):])
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE, _NOTHING, DEFAULT = range(10)
#The background is set with 40 plus the number of the color, and the foreground with 30
@ -63,7 +73,6 @@ COLOR_PATTERN = "%s%s%%s%s" % (COLOR_SEQ, COLOR_SEQ, RESET_SEQ)
LEVEL_COLOR_MAPPING = {
logging.DEBUG: (BLUE, DEFAULT),
logging.INFO: (GREEN, DEFAULT),
logging.TEST: (WHITE, BLUE),
logging.WARNING: (YELLOW, DEFAULT),
logging.ERROR: (RED, DEFAULT),
logging.CRITICAL: (WHITE, RED),
@ -130,38 +139,12 @@ def init_logger():
handler.setFormatter(formatter)
# Configure handlers
default_config = [
'openerp.netsvc.rpc.request:INFO',
'openerp.netsvc.rpc.response:INFO',
'openerp.addons.web.http:INFO',
'openerp.sql_db:INFO',
':INFO',
]
if tools.config['log_level'] == 'info':
pseudo_config = []
elif tools.config['log_level'] == 'debug_rpc':
pseudo_config = ['openerp:DEBUG','openerp.netsvc.rpc.request:DEBUG']
elif tools.config['log_level'] == 'debug_rpc_answer':
pseudo_config = ['openerp:DEBUG','openerp.netsvc.rpc.request:DEBUG', 'openerp.netsvc.rpc.response:DEBUG']
elif tools.config['log_level'] == 'debug':
pseudo_config = ['openerp:DEBUG']
elif tools.config['log_level'] == 'test':
pseudo_config = ['openerp:TEST']
elif tools.config['log_level'] == 'warn':
pseudo_config = ['openerp:WARNING']
elif tools.config['log_level'] == 'error':
pseudo_config = ['openerp:ERROR']
elif tools.config['log_level'] == 'critical':
pseudo_config = ['openerp:CRITICAL']
elif tools.config['log_level'] == 'debug_sql':
pseudo_config = ['openerp.sql_db:DEBUG']
else:
pseudo_config = []
pseudo_config = PSEUDOCONFIG_MAPPER.get(tools.config['log_level'], [])
logconfig = tools.config['log_handler']
for logconfig_item in default_config + pseudo_config + logconfig:
logging_configurations = DEFAULT_LOG_CONFIGURATION + pseudo_config + logconfig
for logconfig_item in logging_configurations:
loggername, level = logconfig_item.split(':')
level = getattr(logging, level, logging.INFO)
logger = logging.getLogger(loggername)
@ -171,9 +154,28 @@ def init_logger():
if loggername != '':
logger.propagate = False
for logconfig_item in default_config + pseudo_config + logconfig:
for logconfig_item in logging_configurations:
_logger.debug('logger level set: "%s"', logconfig_item)
DEFAULT_LOG_CONFIGURATION = [
'openerp.workflow.workitem:WARNING',
'openerp.netsvc.rpc.request:INFO',
'openerp.netsvc.rpc.response:INFO',
'openerp.addons.web.http:INFO',
'openerp.sql_db:INFO',
':INFO',
]
PSEUDOCONFIG_MAPPER = {
'debug_rpc_answer': ['openerp:DEBUG','openerp.netsvc.rpc.request:DEBUG', 'openerp.netsvc.rpc.response:DEBUG'],
'debug_rpc': ['openerp:DEBUG','openerp.netsvc.rpc.request:DEBUG'],
'debug': ['openerp:DEBUG'],
'debug_sql': ['openerp.sql_db:DEBUG'],
'info': [],
'warn': ['openerp:WARNING'],
'error': ['openerp:ERROR'],
'critical': ['openerp:CRITICAL'],
}
# A alternative logging scheme for automated runs of the
# server intended to test it.
def init_alternative_logger():
@ -216,8 +218,7 @@ def dispatch_rpc(service_name, method, params):
if rpc_request_flag or rpc_response_flag:
start_time = time.time()
start_rss, start_vms = 0, 0
if psutil:
start_rss, start_vms = psutil.Process(os.getpid()).get_memory_info()
start_rss, start_vms = psutil.Process(os.getpid()).get_memory_info()
if rpc_request and rpc_response_flag:
log(rpc_request,logging.DEBUG,'%s.%s'%(service_name,method), replace_request_password(params))
@ -238,8 +239,7 @@ def dispatch_rpc(service_name, method, params):
if rpc_request_flag or rpc_response_flag:
end_time = time.time()
end_rss, end_vms = 0, 0
if psutil:
end_rss, end_vms = psutil.Process(os.getpid()).get_memory_info()
end_rss, end_vms = psutil.Process(os.getpid()).get_memory_info()
logline = '%s.%s time:%.3fs mem: %sk -> %sk (diff: %sk)' % (service_name, method, end_time - start_time, start_vms / 1024, end_vms / 1024, (end_vms - start_vms)/1024)
if rpc_response_flag:
log(rpc_response,logging.DEBUG, logline, result)

View File

@ -5155,6 +5155,15 @@ class BaseModel(object):
get_xml_id = get_external_id
_get_xml_ids = _get_external_ids
def print_report(self, cr, uid, ids, name, data, context=None):
"""
Render the report `name` for the given IDs. The report must be defined
for this model, not another.
"""
report = self.pool['ir.actions.report.xml']._lookup_report(cr, name)
assert self._name == report.table
return report.create(cr, uid, ids, data, context)
# Transience
def is_transient(self):
""" Return whether the model is transient.

View File

@ -25,27 +25,36 @@
"""
import logging
import openerp.conf.deprecation
from openerp.modules.registry import RegistryManager
_logger = logging.getLogger(__name__)
def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False):
"""Create and return a database connection and a newly initialized registry."""
assert openerp.conf.deprecation.openerp_pooler
_logger.warning('openerp.pooler.get_db_and_pool() is deprecated.')
registry = RegistryManager.get(db_name, force_demo, status, update_module)
return registry.db, registry
def restart_pool(db_name, force_demo=False, status=None, update_module=False):
"""Delete an existing registry and return a database connection and a newly initialized registry."""
_logger.warning('openerp.pooler.restart_pool() is deprecated.')
assert openerp.conf.deprecation.openerp_pooler
registry = RegistryManager.new(db_name, force_demo, status, update_module)
return registry.db, registry
def get_db(db_name):
"""Return a database connection. The corresponding registry is initialized."""
assert openerp.conf.deprecation.openerp_pooler
return get_db_and_pool(db_name)[0]
def get_pool(db_name, force_demo=False, status=None, update_module=False):
"""Return a model registry."""
assert openerp.conf.deprecation.openerp_pooler
return get_db_and_pool(db_name, force_demo, status, update_module)[1]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,6 +19,8 @@
#
##############################################################################
import openerp
import interface
import print_xml
import print_fnc
@ -30,6 +32,13 @@ import report_sxw
import printscreen
def render_report(cr, uid, ids, name, data, context=None):
"""
Helper to call ``ir.actions.report.xml.render_report()``.
"""
registry = openerp.modules.registry.RegistryManager.get(cr.dbname)
return registry['ir.actions.report.xml'].render_report(cr, uid, ids, name, data, context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -22,6 +22,7 @@
import os
import time
import openerp
import openerp.tools as tools
from openerp.tools.safe_eval import safe_eval as eval
import print_xml
@ -31,7 +32,6 @@ import common
from openerp.osv.osv import except_osv
from openerp.osv.orm import browse_null
from openerp.osv.orm import browse_record_list
import openerp.pooler as pooler
from pychart import *
import misc
import cStringIO
@ -127,22 +127,22 @@ class report_custom(report_int):
def create(self, cr, uid, ids, datas, context=None):
if not context:
context={}
self.pool = pooler.get_pool(cr.dbname)
report = self.pool.get('ir.report.custom').browse(cr, uid, [datas['report_id']])[0]
self.pool = openerp.registry(cr.dbname)
report = self.pool['ir.report.custom'].browse(cr, uid, [datas['report_id']])[0]
datas['model'] = report.model_id.model
if report.menu_id:
ids = self.pool.get(report.model_id.model).search(cr, uid, [])
ids = self.pool[report.model_id.model].search(cr, uid, [])
datas['ids'] = ids
report_id = datas['report_id']
report = self.pool.get('ir.report.custom').read(cr, uid, [report_id], context=context)[0]
fields = self.pool.get('ir.report.custom.fields').read(cr, uid, report['fields_child0'], context=context)
report = self.pool['ir.report.custom'].read(cr, uid, [report_id], context=context)[0]
fields = self.pool['ir.report.custom.fields'].read(cr, uid, report['fields_child0'], context=context)
fields.sort(lambda x,y : x['sequence'] - y['sequence'])
if report['field_parent']:
parent_field = self.pool.get('ir.model.fields').read(cr, uid, [report['field_parent'][0]], ['model'])
model_name = self.pool.get('ir.model').read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model']
parent_field = self.pool['ir.model.fields'].read(cr, uid, [report['field_parent'][0]], ['model'])
model_name = self.pool['ir.model'].read(cr, uid, [report['model_id'][0]], ['model'], context=context)[0]['model']
fct = {
'id': lambda x: x,
@ -158,7 +158,7 @@ class report_custom(report_int):
field_child = f['field_child'+str(i)]
if field_child:
row.append(
self.pool.get('ir.model.fields').read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name']
self.pool['ir.model.fields'].read(cr, uid, [field_child[0]], ['name'], context=context)[0]['name']
)
if f['fc'+str(i)+'_operande']:
fct_name = 'id'
@ -171,7 +171,7 @@ class report_custom(report_int):
cond.append(None)
new_fields.append(row)
new_cond.append(cond)
objs = self.pool.get(model_name).browse(cr, uid, ids)
objs = self.pool[model_name].browse(cr, uid, ids)
# Group by
groupby = None
@ -340,7 +340,7 @@ class report_custom(report_int):
def _create_lines(self, cr, uid, ids, report, fields, results, context):
pool = pooler.get_pool(cr.dbname)
pool = openerp.registry(cr.dbname)
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
@ -371,7 +371,7 @@ class report_custom(report_int):
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype'])
type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]
@ -444,7 +444,7 @@ class report_custom(report_int):
def _create_bars(self, cr, uid, ids, report, fields, results, context):
pool = pooler.get_pool(cr.dbname)
pool = openerp.registry(cr.dbname)
pdf_string = cStringIO.StringIO()
can = canvas.init(fname=pdf_string, format='pdf')
@ -472,7 +472,7 @@ class report_custom(report_int):
for f in fields:
field_id = (f['field_child3'] and f['field_child3'][0]) or (f['field_child2'] and f['field_child2'][0]) or (f['field_child1'] and f['field_child1'][0]) or (f['field_child0'] and f['field_child0'][0])
if field_id:
type = pool.get('ir.model.fields').read(cr, uid, [field_id],['ttype'])
type = pool['ir.model.fields'].read(cr, uid, [field_id],['ttype'])
if type[0]['ttype'] == 'date':
date_idx = idx
fct[idx] = process_date[report['frequency']]

View File

@ -23,8 +23,10 @@ import os
import re
from lxml import etree
import openerp.pooler as pooler
import openerp
import openerp
import openerp.tools as tools
import openerp.modules
import print_xml
@ -43,11 +45,16 @@ class report_int(object):
_reports = {}
def __init__(self, name):
if not name.startswith('report.'):
raise Exception('ConceptionError, bad report name, should start with "report."')
assert name not in self._reports, 'The report "%s" already exists!' % name
self._reports[name] = self
def __init__(self, name, register=True):
if register:
assert openerp.conf.deprecation.allow_report_int_registration
assert name.startswith('report.'), 'Report names should start with "report.".'
assert name not in self._reports, 'The report "%s" already exists.' % name
self._reports[name] = self
else:
# The report is instanciated at each use site, which is ok.
pass
self.__name = name
self.name = name
@ -65,8 +72,8 @@ class report_rml(report_int):
XML -> DATAS -> RML -> PDF -> HTML
using a XSL:RML transformation
"""
def __init__(self, name, table, tmpl, xsl):
super(report_rml, self).__init__(name)
def __init__(self, name, table, tmpl, xsl, register=True):
super(report_rml, self).__init__(name, register=register)
self.table = table
self.internal_header=False
self.tmpl = tmpl
@ -90,8 +97,8 @@ class report_rml(report_int):
if report_type == 'raw':
return xml, report_type
rml = self.create_rml(cr, xml, uid, context)
pool = pooler.get_pool(cr.dbname)
ir_actions_report_xml_obj = pool.get('ir.actions.report.xml')
registry = openerp.registry(cr.dbname)
ir_actions_report_xml_obj = registry['ir.actions.report.xml']
report_xml_ids = ir_actions_report_xml_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context)
self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'OpenERP Report'
create_doc = self.generators[report_type]
@ -140,8 +147,8 @@ class report_rml(report_int):
self.internal_header=True
if not context:
context={}
pool = pooler.get_pool(cr.dbname)
ir_translation_obj = pool.get('ir.translation')
registry = openerp.registry(cr.dbname)
ir_translation_obj = registry['ir.translation']
# In some case we might not use xsl ...
if not self.xsl:

View File

@ -20,11 +20,11 @@
##############################################################################
from lxml import etree
import openerp
import openerp.tools as tools
from openerp.tools.safe_eval import safe_eval
import print_fnc
from openerp.osv.orm import browse_null, browse_record
import openerp.pooler as pooler
class InheritDict(dict):
# Might be usefull when we're doing name lookup for call or eval.
@ -54,7 +54,7 @@ class document(object):
def __init__(self, cr, uid, datas, func=False):
# create a new document
self.cr = cr
self.pool = pooler.get_pool(cr.dbname)
self.pool = openerp.registry(cr.dbname)
self.func = func or {}
self.datas = datas
self.uid = uid
@ -134,8 +134,8 @@ class document(object):
value = self.get_value(browser, attrs['name'])
ids = self.pool.get('ir.attachment').search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))])
datas = self.pool.get('ir.attachment').read(self.cr, self.uid, ids)
ids = self.pool['ir.attachment'].search(self.cr, self.uid, [('res_model','=',model),('res_id','=',int(value))])
datas = self.pool['ir.attachment'].read(self.cr, self.uid, ids)
if len(datas):
# if there are several, pick first
@ -264,7 +264,7 @@ class document(object):
def parse_tree(self, ids, model, context=None):
if not context:
context={}
browser = self.pool.get(model).browse(self.cr, self.uid, ids, context)
browser = self.pool[model].browse(self.cr, self.uid, ids, context)
self.parse_node(self.dom, self.doc, browser)
def parse_string(self, xml, ids, model, context=None):

View File

@ -19,8 +19,8 @@
#
##############################################################################
import openerp
from openerp.report.interface import report_int
import openerp.pooler as pooler
import openerp.tools as tools
from openerp.report import render
@ -55,8 +55,8 @@ class report_printscreen_list(report_int):
if not context:
context={}
datas['ids'] = ids
pool = pooler.get_pool(cr.dbname)
model = pool.get(datas['model'])
registry = openerp.registry(cr.dbname)
model = registry[datas['model']]
# title come from description of model which are specified in py file.
self.title = model._description
result = model.fields_view_get(cr, uid, view_type='form', context=context)

View File

@ -19,8 +19,8 @@
#
##############################################################################
import openerp
from openerp.report.interface import report_int
import openerp.pooler as pooler
import openerp.tools as tools
from openerp.tools.safe_eval import safe_eval as eval
from lxml import etree
@ -66,12 +66,12 @@ class report_printscreen_list(report_int):
self.context = context
self.groupby = context.get('group_by',[])
self.groupby_no_leaf = context.get('group_by_no_leaf',False)
pool = pooler.get_pool(cr.dbname)
model = pool.get(datas['model'])
model_id = pool.get('ir.model').search(cr, uid, [('model','=',model._name)])
registry = openerp.registry(cr.dbname)
model = registry[datas['model']]
model_id = registry['ir.model'].search(cr, uid, [('model','=',model._name)])
model_desc = model._description
if model_id:
model_desc = pool.get('ir.model').browse(cr, uid, model_id[0], context).name
model_desc = registry['ir.model'].browse(cr, uid, model_id[0], context).name
self.title = model_desc
datas['ids'] = ids
result = model.fields_view_get(cr, uid, view_type='tree', context=context)
@ -134,8 +134,9 @@ class report_printscreen_list(report_int):
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
_append_node('report-header', title)
_append_node('company', pooler.get_pool(self.cr.dbname).get('res.users').browse(self.cr,uid,uid).company_id.name)
rpt_obj = pooler.get_pool(self.cr.dbname).get('res.users')
registry = openerp.registry(self.cr.dbname)
_append_node('company', registry['res.users'].browse(self.cr,uid,uid).company_id.name)
rpt_obj = registry['res.users']
rml_obj=report_sxw.rml_parse(self.cr, uid, rpt_obj._name,context)
_append_node('header-date', str(rml_obj.formatLang(time.strftime("%Y-%m-%d"),date=True))+' ' + str(time.strftime("%H:%M")))
l = []

View File

@ -131,14 +131,11 @@ def _process_text(self, txt):
to_translate = tools.ustr(sps.pop(0))
result += tools.ustr(self.localcontext.get('translate', lambda x:x)(to_translate))
if sps:
try:
txt = None
expr = sps.pop(0)
txt = eval(expr, self.localcontext)
if txt and isinstance(txt, basestring):
txt = tools.ustr(txt)
except Exception:
pass
txt = None
expr = sps.pop(0)
txt = eval(expr, self.localcontext)
if txt and isinstance(txt, basestring):
txt = tools.ustr(txt)
if isinstance(txt, basestring):
result += txt
elif txt and (txt is not None) and (txt is not False):

View File

@ -29,10 +29,11 @@ import time
from interface import report_rml
import preprocess
import logging
import openerp.pooler as pooler
import openerp.tools as tools
import zipfile
import common
import openerp
from openerp.osv.fields import float as float_field, function as function_field, datetime as datetime_field
from openerp.tools.translate import _
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
@ -152,8 +153,8 @@ class rml_parse(object):
context={}
self.cr = cr
self.uid = uid
self.pool = pooler.get_pool(cr.dbname)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
self.pool = openerp.registry(cr.dbname)
user = self.pool['res.users'].browse(cr, uid, uid, context=context)
self.localcontext = {
'user': user,
'setCompany': self.setCompany,
@ -220,7 +221,7 @@ class rml_parse(object):
model = 'ir.attachment'
try :
id = int(id)
res = self.pool.get(model).read(self.cr,self.uid,id)
res = self.pool[model].read(self.cr,self.uid,id)
if field :
return res[field]
elif model =='ir.attachment' :
@ -237,7 +238,7 @@ class rml_parse(object):
obj._context['lang'] = lang
def _get_lang_dict(self):
pool_lang = self.pool.get('res.lang')
pool_lang = self.pool['res.lang']
lang = self.localcontext.get('lang', 'en_US') or 'en_US'
lang_ids = pool_lang.search(self.cr,self.uid,[('code','=',lang)])[0]
lang_obj = pool_lang.browse(self.cr,self.uid,lang_ids)
@ -252,7 +253,7 @@ class rml_parse(object):
def get_digits(self, obj=None, f=None, dp=None):
d = DEFAULT_DIGITS = 2
if dp:
decimal_precision_obj = self.pool.get('decimal.precision')
decimal_precision_obj = self.pool['decimal.precision']
ids = decimal_precision_obj.search(self.cr, self.uid, [('name', '=', dp)])
if ids:
d = decimal_precision_obj.browse(self.cr, self.uid, ids)[0].digits
@ -323,7 +324,7 @@ class rml_parse(object):
return res
def display_address(self, address_browse_record):
return self.pool.get('res.partner')._display_address(self.cr, self.uid, address_browse_record)
return self.pool['res.partner']._display_address(self.cr, self.uid, address_browse_record)
def repeatIn(self, lst, name,nodes_parent=False):
ret_lst = []
@ -334,7 +335,7 @@ class rml_parse(object):
def _translate(self,text):
lang = self.localcontext['lang']
if lang and text and not text.isspace():
transl_obj = self.pool.get('ir.translation')
transl_obj = self.pool['ir.translation']
piece_list = self._transl_regex.split(text)
for pn in range(len(piece_list)):
if not self._transl_regex.match(piece_list[pn]):
@ -388,8 +389,19 @@ class rml_parse(object):
self.setCompany(objects[0].company_id)
class report_sxw(report_rml, preprocess.report):
def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False):
report_rml.__init__(self, name, table, rml, '')
"""
The register=True kwarg has been added to help remove the
openerp.netsvc.LocalService() indirection and the related
openerp.report.interface.report_int._reports dictionary:
report_sxw registered in XML with auto=False are also registered in Python.
In that case, they are registered in the above dictionary. Since
registration is automatically done upon instanciation, and that
instanciation is needed before rendering, a way was needed to
instanciate-without-register a report. In the future, no report
should be registered in the above dictionary and it will be dropped.
"""
def __init__(self, name, table, rml=False, parser=rml_parse, header='external', store=False, register=True):
report_rml.__init__(self, name, table, rml, '', register=register)
self.name = name
self.parser = parser
self.header = header
@ -399,7 +411,7 @@ class report_sxw(report_rml, preprocess.report):
self.internal_header=True
def getObjects(self, cr, uid, ids, context):
table_obj = pooler.get_pool(cr.dbname).get(self.table)
table_obj = openerp.registry(cr.dbname)[self.table]
return table_obj.browse(cr, uid, ids, list_class=browse_record_list, context=context, fields_process=_fields_process)
def create(self, cr, uid, ids, data, context=None):
@ -409,8 +421,8 @@ class report_sxw(report_rml, preprocess.report):
context.update(internal_header=self.internal_header)
# skip osv.fields.sanitize_binary_value() because we want the raw bytes in all cases
context.update(bin_raw=True)
pool = pooler.get_pool(cr.dbname)
ir_obj = pool.get('ir.actions.report.xml')
registry = openerp.registry(cr.dbname)
ir_obj = registry['ir.actions.report.xml']
report_xml_ids = ir_obj.search(cr, uid,
[('report_name', '=', self.name[7:])], context=context)
if report_xml_ids:
@ -458,7 +470,7 @@ class report_sxw(report_rml, preprocess.report):
def create_source_pdf(self, cr, uid, ids, data, report_xml, context=None):
if not context:
context={}
pool = pooler.get_pool(cr.dbname)
registry = openerp.registry(cr.dbname)
attach = report_xml.attachment
if attach:
objs = self.getObjects(cr, uid, ids, context)
@ -467,9 +479,9 @@ class report_sxw(report_rml, preprocess.report):
aname = eval(attach, {'object':obj, 'time':time})
result = False
if report_xml.attachment_use and aname and context.get('attachment_use', True):
aids = pool.get('ir.attachment').search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)])
aids = registry['ir.attachment'].search(cr, uid, [('datas_fname','=',aname+'.pdf'),('res_model','=',self.table),('res_id','=',obj.id)])
if aids:
brow_rec = pool.get('ir.attachment').browse(cr, uid, aids[0])
brow_rec = registry['ir.attachment'].browse(cr, uid, aids[0])
if not brow_rec.datas:
continue
d = base64.decodestring(brow_rec.datas)
@ -487,7 +499,7 @@ class report_sxw(report_rml, preprocess.report):
# field.
ctx = dict(context)
ctx.pop('default_type', None)
pool.get('ir.attachment').create(cr, uid, {
registry['ir.attachment'].create(cr, uid, {
'name': aname,
'datas': base64.encodestring(result[0]),
'datas_fname': name,

View File

@ -1,10 +1,7 @@
# -*- coding: utf-8 -*-
import logging
import threading
import openerp.osv.orm # TODO use openerp.exceptions
import openerp.pooler
import openerp.release
import openerp.tools
@ -20,11 +17,10 @@ RPC_VERSION_1 = {
}
def dispatch(method, params):
if method in ['login', 'about', 'timezone_get', 'get_server_environment',
'login_message','get_stats', 'check_connectivity',
'list_http_services', 'version', 'authenticate']:
if method in ['login', 'about', 'timezone_get',
'version', 'authenticate']:
pass
elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel', 'get_os_time', 'get_sqlcount']:
elif method in ['set_loglevel']:
passwd = params[0]
params = params[1:]
security.check_super(passwd)
@ -43,7 +39,7 @@ def exp_login(db, login, password):
return res or False
def exp_authenticate(db, login, password, user_agent_env):
res_users = openerp.pooler.get_pool(db).get('res.users')
res_users = openerp.registry(db)['res.users']
return res_users.authenticate(db, login, password, user_agent_env)
def exp_version():
@ -65,136 +61,9 @@ def exp_about(extended=False):
def exp_timezone_get(db, login, password):
return openerp.tools.misc.get_server_timezone()
def exp_get_available_updates(contract_id, contract_password):
import openerp.tools.maintenance as tm
try:
rc = tm.remote_contract(contract_id, contract_password)
if not rc.id:
raise tm.RemoteContractException('This contract does not exist or is not active')
return rc.get_available_updates(rc.id, openerp.modules.get_modules_with_version())
except tm.RemoteContractException, e:
raise openerp.osv.orm.except_orm('Migration Error', str(e))
def exp_get_migration_scripts(contract_id, contract_password):
import openerp.tools.maintenance as tm
try:
rc = tm.remote_contract(contract_id, contract_password)
if not rc.id:
raise tm.RemoteContractException('This contract does not exist or is not active')
if rc.status != 'full':
raise tm.RemoteContractException('Can not get updates for a partial contract')
_logger.info('starting migration with contract %s', rc.name)
zips = rc.retrieve_updates(rc.id, openerp.modules.get_modules_with_version())
from shutil import rmtree, copytree, copy
backup_directory = os.path.join(openerp.tools.config['root_path'], 'backup', time.strftime('%Y-%m-%d-%H-%M'))
if zips and not os.path.isdir(backup_directory):
_logger.info('create a new backup directory to store the old modules: %s', backup_directory)
os.makedirs(backup_directory)
for module in zips:
_logger.info('upgrade module %s', module)
mp = openerp.modules.get_module_path(module)
if mp:
if os.path.isdir(mp):
copytree(mp, os.path.join(backup_directory, module))
if os.path.islink(mp):
os.unlink(mp)
else:
rmtree(mp)
else:
copy(mp + 'zip', backup_directory)
os.unlink(mp + '.zip')
try:
try:
base64_decoded = base64.decodestring(zips[module])
except Exception:
_logger.error('unable to read the module %s', module)
raise
zip_contents = StringIO(base64_decoded)
zip_contents.seek(0)
try:
try:
openerp.tools.extract_zip_file(zip_contents, openerp.tools.config['addons_path'] )
except Exception:
_logger.error('unable to extract the module %s', module)
rmtree(module)
raise
finally:
zip_contents.close()
except Exception:
_logger.error('restore the previous version of the module %s', module)
nmp = os.path.join(backup_directory, module)
if os.path.isdir(nmp):
copytree(nmp, openerp.tools.config['addons_path'])
else:
copy(nmp+'.zip', openerp.tools.config['addons_path'])
raise
return True
except tm.RemoteContractException, e:
raise openerp.osv.orm.except_orm('Migration Error', str(e))
except Exception, e:
_logger.exception('Exception in get_migration_script:')
raise
def exp_get_server_environment():
os_lang = '.'.join( [x for x in locale.getdefaultlocale() if x] )
if not os_lang:
os_lang = 'NOT SET'
environment = '\nEnvironment Information : \n' \
'System : %s\n' \
'OS Name : %s\n' \
%(platform.platform(), platform.os.name)
if os.name == 'posix':
if platform.system() == 'Linux':
lsbinfo = os.popen('lsb_release -a').read()
environment += '%s'% lsbinfo
else:
environment += 'Your System is not lsb compliant\n'
environment += 'Operating System Release : %s\n' \
'Operating System Version : %s\n' \
'Operating System Architecture : %s\n' \
'Operating System Locale : %s\n'\
'Python Version : %s\n'\
'OpenERP-Server Version : %s'\
%(platform.release(), platform.version(), platform.architecture()[0],
os_lang, platform.python_version(), openerp.release.version)
return environment
def exp_login_message():
return openerp.tools.config.get('login_message', False)
def exp_set_loglevel(loglevel, logger=None):
# TODO Previously, the level was set on the now deprecated
# `openerp.netsvc.Logger` class.
return True
def exp_get_stats():
res = "OpenERP server: %d threads\n" % threading.active_count()
res += netsvc.Server.allStats()
return res
def exp_list_http_services():
return http_server.list_http_services()
def exp_check_connectivity():
return bool(sql_db.db_connect('postgres'))
def exp_get_os_time():
return os.times()
def exp_get_sqlcount():
if not logging.getLogger('openerp.sql_db').isEnabledFor(logging.DEBUG):
_logger.warning("Counters of SQL will not be reliable unless logger openerp.sql_db is set to level DEBUG or higer.")
return sql_db.sql_counter
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -7,8 +7,8 @@ import os
import threading
import traceback
import openerp
from openerp import SUPERUSER_ID
import openerp.pooler
import openerp.release
import openerp.sql_db
import openerp.tools
@ -28,7 +28,7 @@ def _initialize_db(id, db_name, demo, lang, user_password):
try:
self_actions[id]['progress'] = 0
cr = openerp.sql_db.db_connect(db_name).cursor()
openerp.modules.db.initialize(cr) # TODO this should be removed as it is done by pooler.restart_pool.
openerp.modules.db.initialize(cr) # TODO this should be removed as it is done by RegistryManager.new().
openerp.tools.config['lang'] = lang
cr.commit()
finally:
@ -36,20 +36,20 @@ def _initialize_db(id, db_name, demo, lang, user_password):
cr.close()
cr = None
pool = openerp.pooler.restart_pool(db_name, demo, self_actions[id],
update_module=True)[1]
registry = openerp.modules.registry.RegistryManager.new(
db_name, demo, self_actions[id], update_module=True)[1]
try:
cr = openerp.sql_db.db_connect(db_name).cursor()
if lang:
modobj = pool.get('ir.module.module')
modobj = registry['ir.module.module']
mids = modobj.search(cr, SUPERUSER_ID, [('state', '=', 'installed')])
modobj.update_translations(cr, SUPERUSER_ID, mids, lang)
# update admin's password and lang
values = {'password': user_password, 'lang': lang}
pool.get('res.users').write(cr, SUPERUSER_ID, [SUPERUSER_ID], values)
registry['res.users'].write(cr, SUPERUSER_ID, [SUPERUSER_ID], values)
cr.execute('SELECT login, password FROM res_users ORDER BY login')
self_actions[id].update(users=cr.dictfetchall(), clean=True)
@ -351,7 +351,7 @@ def exp_migrate_databases(databases):
for db in databases:
_logger.info('migrate database %s', db)
openerp.tools.config['update']['base'] = True
openerp.pooler.restart_pool(db, force_demo=False, update_module=True)
openerp.modules.registry.RegistryManager.new(db, force_demo=False, update_module=True)
return True
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -61,7 +61,7 @@ def check(f):
# callable. We need to find the right parameters to call
# the orm._sql_message(self, cr, uid, ids, context) function,
# or we skip..
# our signature is f(osv_pool, dbname [,uid, obj, method, args])
# our signature is f(registry, dbname [,uid, obj, method, args])
try:
if args and len(args) > 1:
# TODO self doesn't exist, but was already wrong before (it was not a registry but just the object_service.
@ -95,14 +95,14 @@ def check(f):
return tr(src, 'code')
try:
if openerp.pooler.get_pool(dbname)._init:
if openerp.registry(dbname)._init:
raise openerp.exceptions.Warning('Currently, this database is not fully loaded and can not be used.')
return f(dbname, *args, **kwargs)
except IntegrityError, inst:
osv_pool = openerp.pooler.get_pool(dbname)
for key in osv_pool._sql_error.keys():
registry = openerp.registry(dbname)
for key in registry._sql_error.keys():
if key in inst[0]:
raise openerp.osv.orm.except_orm(_('Constraint Error'), tr(osv_pool._sql_error[key], 'sql_constraint') or inst[0])
raise openerp.osv.orm.except_orm(_('Constraint Error'), tr(registry._sql_error[key], 'sql_constraint') or inst[0])
if inst.pgcode in (errorcodes.NOT_NULL_VIOLATION, errorcodes.FOREIGN_KEY_VIOLATION, errorcodes.RESTRICT_VIOLATION):
msg = _('The operation cannot be completed, probably due to the following:\n- deletion: you may be trying to delete a record while other records still reference it\n- creation/update: a mandatory field is not correctly set')
_logger.debug("IntegrityError", exc_info=True)
@ -116,7 +116,7 @@ def check(f):
last_quote_begin = errortxt.rfind('"', 0, last_quote_end)
model_name = table = errortxt[last_quote_begin+1:last_quote_end].strip()
model = table.replace("_",".")
model_obj = osv_pool.get(model)
model_obj = registry.get(model)
if model_obj:
model_name = model_obj._description or model_obj._name
msg += _('\n\n[object with reference: %s - %s]') % (model_name, model)
@ -129,7 +129,7 @@ def check(f):
return wrapper
def execute_cr(cr, uid, obj, method, *args, **kw):
object = openerp.pooler.get_pool(cr.dbname).get(obj)
object = openerp.registry(cr.dbname).get(obj)
if not object:
raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj))
return getattr(object, method)(cr, uid, *args, **kw)
@ -140,7 +140,7 @@ def execute_kw(db, uid, obj, method, args, kw=None):
@check
def execute(db, uid, obj, method, *args, **kw):
threading.currentThread().dbname = db
cr = openerp.pooler.get_db(db).cursor()
cr = openerp.registry(db).db.cursor()
try:
try:
if method.startswith('_'):
@ -157,7 +157,7 @@ def execute(db, uid, obj, method, *args, **kw):
return res
def exec_workflow_cr(cr, uid, obj, signal, *args):
object = openerp.pooler.get_pool(cr.dbname).get(obj)
object = openerp.registry(cr.dbname).get(obj)
if not object:
raise except_orm('Object Error', 'Object %s doesn\'t exist' % str(obj))
res_id = args[0]
@ -165,7 +165,7 @@ def exec_workflow_cr(cr, uid, obj, signal, *args):
@check
def exec_workflow(db, uid, obj, signal, *args):
cr = openerp.pooler.get_db(db).cursor()
cr = openerp.registry(db).db.cursor()
try:
try:
res = exec_workflow_cr(cr, uid, obj, signal, *args)

View File

@ -5,8 +5,8 @@ import logging
import sys
import threading
import openerp.netsvc
import openerp.pooler
import openerp
import openerp.report
from openerp import tools
import security
@ -49,10 +49,9 @@ def exp_render_report(db, uid, object, ids, datas=None, context=None):
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
cr = openerp.pooler.get_db(db).cursor()
cr = openerp.registry(db).db.cursor()
try:
obj = openerp.netsvc.LocalService('report.'+object)
(result, format) = obj.create(cr, uid, ids, datas, context)
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
if not result:
tb = sys.exc_info()
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)
@ -88,10 +87,9 @@ def exp_report(db, uid, object, ids, datas=None, context=None):
self_reports[id] = {'uid': uid, 'result': False, 'state': False, 'exception': None}
def go(id, uid, ids, datas, context):
cr = openerp.pooler.get_db(db).cursor()
cr = openerp.registry(db).db.cursor()
try:
obj = openerp.netsvc.LocalService('report.'+object)
(result, format) = obj.create(cr, uid, ids, datas, context)
result, format = openerp.report.render_report(cr, uid, ids, object, datas, context)
if not result:
tb = sys.exc_info()
self_reports[id]['exception'] = openerp.exceptions.DeferredException('RML is not available at specified location or not enough data to print!', tb)

View File

@ -19,25 +19,20 @@
#
##############################################################################
import openerp.exceptions
import openerp.pooler as pooler
import openerp.tools as tools
import openerp
def login(db, login, password):
pool = pooler.get_pool(db)
user_obj = pool.get('res.users')
return user_obj.login(db, login, password)
res_users = openerp.registry(db)['res.users']
return res_users.login(db, login, password)
def check_super(passwd):
if passwd == tools.config['admin_passwd']:
if passwd == openerp.tools.config['admin_passwd']:
return True
else:
raise openerp.exceptions.AccessDenied()
def check(db, uid, passwd):
pool = pooler.get_pool(db)
user_obj = pool.get('res.users')
return user_obj.check(db, uid, passwd)
res_users = openerp.registry(db)['res.users']
return res_users.check(db, uid, passwd)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -25,8 +25,6 @@
The PostgreSQL connector is a connectivity layer between the OpenERP code and
the database, *not* a database abstraction toolkit. Database abstraction is what
the ORM does, in fact.
See also: the `pooler` module
"""

View File

@ -66,7 +66,6 @@ class configmanager(object):
self.options = {
'admin_passwd': 'admin',
'csv_internal_sep': ',',
'login_message': False,
'publisher_warranty_url': 'http://services.openerp.com/publisher-warranty/',
'reportgz': False,
'root_path': None,
@ -84,7 +83,7 @@ class configmanager(object):
self.config_file = fname
self.has_ssl = check_ssl()
self._LOGLEVELS = dict([(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'TEST', 'DEBUG', 'NOTSET')])
self._LOGLEVELS = dict([(getattr(loglevels, 'LOG_%s' % x), getattr(logging, x)) for x in ('CRITICAL', 'ERROR', 'WARNING', 'INFO', 'DEBUG', 'NOTSET')])
version = "%s %s" % (release.description, release.version)
self.parser = parser = optparse.OptionParser(version=version, option_class=MyOption)

View File

@ -29,7 +29,10 @@ import sys
# for eval context:
import time
import openerp.release as release
import openerp
import openerp.release
import openerp.workflow
import assertion_report
@ -47,7 +50,6 @@ except:
from datetime import datetime, timedelta
from lxml import etree
import misc
import openerp.pooler as pooler
from config import config
from translate import _
@ -77,7 +79,7 @@ def _ref(self, cr):
return lambda x: self.id_get(cr, x)
def _obj(pool, cr, uid, model_str, context=None):
model = pool.get(model_str)
model = pool[model_str]
return lambda x: model.browse(cr, uid, x, context=context)
def _get_idref(self, cr, uid, model_str, context, idref):
@ -85,7 +87,7 @@ def _get_idref(self, cr, uid, model_str, context, idref):
time=time,
DateTime=datetime,
timedelta=timedelta,
version=release.major_version,
version=openerp.release.major_version,
ref=_ref(self, cr),
pytz=pytz)
if len(model_str):
@ -124,10 +126,10 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None):
if f_search:
idref2 = _get_idref(self, cr, uid, f_model, context, idref)
q = unsafe_eval(f_search, idref2)
ids = pool.get(f_model).search(cr, uid, q)
ids = pool[f_model].search(cr, uid, q)
if f_use != 'id':
ids = map(lambda x: x[f_use], pool.get(f_model).read(cr, uid, ids, [f_use]))
_cols = pool.get(f_model)._columns
ids = map(lambda x: x[f_use], pool[f_model].read(cr, uid, ids, [f_use]))
_cols = pool[f_model]._columns
if (f_name in _cols) and _cols[f_name]._type=='many2many':
return ids
f_val = False
@ -196,7 +198,7 @@ def _eval_xml(self, node, pool, cr, uid, idref, context=None):
return_val = _eval_xml(self,n, pool, cr, uid, idref, context)
if return_val is not None:
args.append(return_val)
model = pool.get(node.get('model',''))
model = pool[node.get('model','')]
method = node.get('name','')
res = getattr(model, method)(cr, uid, *args)
return res
@ -256,7 +258,7 @@ class xml_import(object):
maximum one dot. They are used to refer to other modules ID, in the
form: module.record_id""" % (xml_id,)
if module != self.module:
modcnt = self.pool.get('ir.module.module').search_count(self.cr, self.uid, ['&', ('name', '=', module), ('state', 'in', ['installed'])])
modcnt = self.pool['ir.module.module'].search_count(self.cr, self.uid, ['&', ('name', '=', module), ('state', 'in', ['installed'])])
assert modcnt == 1, """The ID "%s" refers to an uninstalled module""" % (xml_id,)
if len(id) > 64:
@ -270,7 +272,7 @@ form: module.record_id""" % (xml_id,)
if d_search:
idref = _get_idref(self, cr, self.uid, d_model, context={}, idref={})
ids = self.pool.get(d_model).search(cr, self.uid, unsafe_eval(d_search, idref))
ids = self.pool[d_model].search(cr, self.uid, unsafe_eval(d_search, idref))
if d_id:
try:
ids.append(self.id_get(cr, d_id))
@ -278,10 +280,10 @@ form: module.record_id""" % (xml_id,)
# d_id cannot be found. doesn't matter in this case
pass
if ids:
self.pool.get(d_model).unlink(cr, self.uid, ids)
self.pool[d_model].unlink(cr, self.uid, ids)
def _remove_ir_values(self, cr, name, value, model):
ir_values_obj = self.pool.get('ir.values')
ir_values_obj = self.pool['ir.values']
ir_value_ids = ir_values_obj.search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)])
if ir_value_ids:
ir_values_obj.unlink(cr, self.uid, ir_value_ids)
@ -294,7 +296,8 @@ form: module.record_id""" % (xml_id,)
res[dest] = rec.get(f,'').encode('utf8')
assert res[dest], "Attribute %s of report is empty !" % (f,)
for field,dest in (('rml','report_rml'),('file','report_rml'),('xml','report_xml'),('xsl','report_xsl'),
('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage')):
('attachment','attachment'),('attachment_use','attachment_use'), ('usage','usage'),
('report_type', 'report_type'), ('parser', 'parser')):
if rec.get(field):
res[dest] = rec.get(field).encode('utf8')
if rec.get('auto'):
@ -304,8 +307,6 @@ form: module.record_id""" % (xml_id,)
res['report_sxw_content'] = sxw_content
if rec.get('header'):
res['header'] = eval(rec.get('header','False'))
if rec.get('report_type'):
res['report_type'] = rec.get('report_type')
res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))
@ -324,14 +325,14 @@ form: module.record_id""" % (xml_id,)
groups_value.append((4, group_id))
res['groups_id'] = groups_value
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.report.xml", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
if not rec.get('menu') or eval(rec.get('menu','False')):
keyword = str(rec.get('keyword', 'client_print_multi'))
value = 'ir.actions.report.xml,'+str(id)
replace = rec.get('replace', True)
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id)
self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, res['name'], [res['model']], value, replace=replace, isobject=True, xml_id=xml_id)
elif self.mode=='update' and eval(rec.get('menu','False'))==False:
# Special check for report having attribute menu=False on update
value = 'ir.actions.report.xml,'+str(id)
@ -367,14 +368,14 @@ form: module.record_id""" % (xml_id,)
groups_value.append((4, group_id))
res['groups_id'] = groups_value
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.wizard", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
# ir_set
if (not rec.get('menu') or eval(rec.get('menu','False'))) and id:
keyword = str(rec.get('keyword','') or 'client_action_multi')
value = 'ir.actions.wizard,'+str(id)
replace = rec.get("replace",'') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, string, [model], value, replace=replace, isobject=True, xml_id=xml_id)
elif self.mode=='update' and (rec.get('menu') and eval(rec.get('menu','False'))==False):
# Special check for wizard having attribute menu=False on update
value = 'ir.actions.wizard,'+str(id)
@ -389,7 +390,7 @@ form: module.record_id""" % (xml_id,)
res = {'name': name, 'url': url, 'target':target}
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.act_url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
id = self.pool['ir.model.data']._update(cr, self.uid, "ir.actions.act_url", self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
def _tag_act_window(self, cr, rec, data_node=None):
@ -489,7 +490,7 @@ form: module.record_id""" % (xml_id,)
res['target'] = rec.get('target','')
if rec.get('multi'):
res['multi'] = rec.get('multi', False)
id = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
id = self.pool['ir.model.data']._update(cr, self.uid, 'ir.actions.act_window', self.module, res, xml_id, noupdate=self.isnoupdate(data_node), mode=self.mode)
self.idref[xml_id] = int(id)
if src_model:
@ -497,7 +498,7 @@ form: module.record_id""" % (xml_id,)
keyword = rec.get('key2','').encode('utf-8') or 'client_action_relate'
value = 'ir.actions.act_window,'+str(id)
replace = rec.get('replace','') or True
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id)
self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', keyword, xml_id, [src_model], value, replace=replace, isobject=True, xml_id=xml_id)
# TODO add remove ir.model.data
def _tag_ir_set(self, cr, rec, data_node=None):
@ -508,7 +509,7 @@ form: module.record_id""" % (xml_id,)
f_name = field.get("name",'').encode('utf-8')
f_val = _eval_xml(self,field,self.pool, cr, self.uid, self.idref)
res[f_name] = f_val
self.pool.get('ir.model.data').ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None))
self.pool['ir.model.data'].ir_set(cr, self.uid, res['key'], res['key2'], res['name'], res['models'], res['value'], replace=res.get('replace',True), isobject=res.get('isobject', False), meta=res.get('meta',None))
def _tag_workflow(self, cr, rec, data_node=None):
if self.isnoupdate(data_node) and self.mode != 'init':
@ -526,9 +527,7 @@ form: module.record_id""" % (xml_id,)
id = _eval_xml(self, rec[0], self.pool, cr, self.uid, self.idref)
uid = self.get_uid(cr, self.uid, data_node, rec)
import openerp.netsvc as netsvc
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, model,
openerp.workflow.trg_validate(uid, model,
id,
str(rec.get('action','')), cr)
@ -563,7 +562,7 @@ form: module.record_id""" % (xml_id,)
else:
# the menuitem does't exist but we are in branch (not a leaf)
_logger.warning('Warning no ID for submenu %s of menu %s !', menu_elem, str(m_l))
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
pid = self.pool['ir.ui.menu'].create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
values['parent_id'] = pid
else:
# The parent attribute was specified, if non-empty determine its ID, otherwise
@ -657,14 +656,14 @@ form: module.record_id""" % (xml_id,)
groups_value.append((4, group_id))
values['groups_id'] = groups_value
pid = self.pool.get('ir.model.data')._update(cr, self.uid, 'ir.ui.menu', self.module, values, rec_id, noupdate=self.isnoupdate(data_node), mode=self.mode, res_id=res and res[0] or False)
pid = self.pool['ir.model.data']._update(cr, self.uid, 'ir.ui.menu', self.module, values, rec_id, noupdate=self.isnoupdate(data_node), mode=self.mode, res_id=res and res[0] or False)
if rec_id and pid:
self.idref[rec_id] = int(pid)
if rec.get('action') and pid:
action = "ir.actions.%s,%d" % (a_type, a_id)
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id)
self.pool['ir.model.data'].ir_set(cr, self.uid, 'action', 'tree_but_open', 'Menuitem', [('ir.ui.menu', int(pid))], action, True, True, xml_id=rec_id)
return 'ir.ui.menu', pid
def _assert_equals(self, f1, f2, prec=4):
@ -675,8 +674,7 @@ form: module.record_id""" % (xml_id,)
return
rec_model = rec.get("model",'').encode('ascii')
model = self.pool.get(rec_model)
assert model, "The model %s does not exist !" % (rec_model,)
model = self.pool[rec_model]
rec_id = rec.get("id",'').encode('ascii')
self._test_xml_id(rec_id)
rec_src = rec.get("search",'').encode('utf8')
@ -692,7 +690,7 @@ form: module.record_id""" % (xml_id,)
ids = [self.id_get(cr, rec_id)]
elif rec_src:
q = unsafe_eval(rec_src, eval_dict)
ids = self.pool.get(rec_model).search(cr, uid, q, context=context)
ids = self.pool[rec_model].search(cr, uid, q, context=context)
if rec_src_count:
count = int(rec_src_count)
if len(ids) != count:
@ -737,8 +735,7 @@ form: module.record_id""" % (xml_id,)
def _tag_record(self, cr, rec, data_node=None):
rec_model = rec.get("model").encode('ascii')
model = self.pool.get(rec_model)
assert model, "The model %s does not exist !" % (rec_model,)
model = self.pool[rec_model]
rec_id = rec.get("id",'').encode('ascii')
rec_context = rec.get("context", None)
if rec_context:
@ -752,7 +749,7 @@ form: module.record_id""" % (xml_id,)
else:
module = self.module
rec_id2 = rec_id
id = self.pool.get('ir.model.data')._update_dummy(cr, self.uid, rec_model, module, rec_id2)
id = self.pool['ir.model.data']._update_dummy(cr, self.uid, rec_model, module, rec_id2)
# check if the resource already existed at the last update
if id:
# if it existed, we don't update the data, but we need to
@ -785,11 +782,11 @@ form: module.record_id""" % (xml_id,)
q = unsafe_eval(f_search, self.idref)
field = []
assert f_model, 'Define an attribute model="..." in your .XML file !'
f_obj = self.pool.get(f_model)
f_obj = self.pool[f_model]
# browse the objects searched
s = f_obj.browse(cr, self.uid, f_obj.search(cr, self.uid, q))
# column definitions of the "local" object
_cols = self.pool.get(rec_model)._columns
_cols = self.pool[rec_model]._columns
# if the current field is many2many
if (f_name in _cols) and _cols[f_name]._type=='many2many':
f_val = [(6, 0, map(lambda x: x[f_use], s))]
@ -815,7 +812,7 @@ form: module.record_id""" % (xml_id,)
f_val = int(f_val)
res[f_name] = f_val
id = self.pool.get('ir.model.data')._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context )
id = self.pool['ir.model.data']._update(cr, self.uid, rec_model, self.module, res, rec_id or False, not self.isnoupdate(data_node), noupdate=self.isnoupdate(data_node), mode=self.mode, context=rec_context )
if rec_id:
self.idref[rec_id] = int(id)
if config.get('import_partial', False):
@ -830,7 +827,7 @@ form: module.record_id""" % (xml_id,)
return res
def model_id_get(self, cr, id_str):
model_data_obj = self.pool.get('ir.model.data')
model_data_obj = self.pool['ir.model.data']
mod = self.module
if '.' in id_str:
mod,id_str = id_str.split('.')
@ -857,7 +854,7 @@ form: module.record_id""" % (xml_id,)
self.module = module
self.cr = cr
self.idref = idref
self.pool = pooler.get_pool(cr.dbname)
self.pool = openerp.registry(cr.dbname)
self.uid = 1
if report is None:
report = assertion_report.assertion_report()
@ -889,8 +886,6 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
#remove folder path from model
head, model = os.path.split(model)
pool = pooler.get_pool(cr.dbname)
input = cStringIO.StringIO(csvcontent) #FIXME
reader = csv.reader(input, quotechar='"', delimiter=',')
fields = reader.next()
@ -915,13 +910,15 @@ def convert_csv_import(cr, module, fname, csvcontent, idref=None, mode='init',
uid = 1
datas = []
for line in reader:
if (not line) or not reduce(lambda x,y: x or y, line) :
if not (line and any(line)):
continue
try:
datas.append(map(lambda x: misc.ustr(x), line))
datas.append(map(misc.ustr, line))
except:
_logger.error("Cannot import the line: %s", line)
result, rows, warning_msg, dummy = pool.get(model).import_data(cr, uid, fields, datas,mode, module, noupdate, filename=fname_partial)
registry = openerp.registry(cr.dbname)
result, rows, warning_msg, dummy = registry[model].import_data(cr, uid, fields, datas,mode, module, noupdate, filename=fname_partial)
if result < 0:
# Report failed import and abort module install
raise Exception(_('Module loading failed: file %s/%s could not be processed:\n %s') % (module, fname, warning_msg))

View File

@ -24,13 +24,13 @@ import cgi
import logging
import lxml.html
import lxml.html.clean as clean
import openerp.pooler as pooler
import random
import re
import socket
import threading
import time
import openerp
from openerp.loglevels import ustr
_logger = logging.getLogger(__name__)
@ -325,13 +325,13 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non
if not cr:
db_name = getattr(threading.currentThread(), 'dbname', None)
if db_name:
local_cr = cr = pooler.get_db(db_name).cursor()
local_cr = cr = openerp.registry(db_name).db.cursor()
else:
raise Exception("No database cursor found, please pass one explicitly")
# Send Email
try:
mail_server_pool = pooler.get_pool(cr.dbname).get('ir.mail_server')
mail_server_pool = openerp.registry(cr.dbname)['ir.mail_server']
res = False
# Pack Message into MIME Object
email_msg = mail_server_pool.build_email(email_from, email_to, subject, body, email_cc, email_bcc, reply_to,

View File

@ -642,21 +642,6 @@ def icons(*a, **kw):
global __icons_list
return [(x, x) for x in __icons_list ]
def extract_zip_file(zip_file, outdirectory):
zf = zipfile.ZipFile(zip_file, 'r')
out = outdirectory
for path in zf.namelist():
tgt = os.path.join(out, path)
tgtdir = os.path.dirname(tgt)
if not os.path.exists(tgtdir):
os.makedirs(tgtdir)
if not tgt.endswith(os.sep):
fp = open(tgt, 'wb')
fp.write(zf.read(path))
fp.close()
zf.close()
def detect_ip_addr():
"""Try a very crude method to figure out a valid external
IP or hostname for the current machine. Don't rely on this

View File

@ -25,16 +25,18 @@
through the code of yaml tests.
"""
import openerp.netsvc as netsvc
import openerp
import openerp.report
import openerp.tools as tools
import logging
import openerp.pooler as pooler
from openerp.tools.safe_eval import safe_eval
from subprocess import Popen, PIPE
import os
import tempfile
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
""" Try to render a report <rname> with contents of ids
@ -49,8 +51,8 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
rname_s = rname[7:]
else:
rname_s = rname
_logger.log(netsvc.logging.TEST, " - Trying %s.create(%r)", rname, ids)
res = netsvc.LocalService(rname).create(cr, uid, ids, data, context)
_test_logger.info(" - Trying %s.create(%r)", rname, ids)
res = openerp.report.render_report(cr, uid, ids, rname_s, data, context)
if not isinstance(res, tuple):
raise RuntimeError("Result of %s.create() should be a (data,format) tuple, now it is a %s" % \
(rname, type(res)))
@ -92,7 +94,7 @@ def try_report(cr, uid, rname, ids, data=None, context=None, our_module=None):
_logger.warning("Report %s produced a \"%s\" chunk, cannot examine it", rname, res_format)
return False
_logger.log(netsvc.logging.TEST, " + Report %s produced correctly.", rname)
_test_logger.info(" + Report %s produced correctly.", rname)
return True
def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
@ -123,10 +125,10 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
context = context.copy() # keep it local
# TODO context fill-up
pool = pooler.get_pool(cr.dbname)
registry = openerp.registry(cr.dbname)
def log_test(msg, *args):
_logger.log(netsvc.logging.TEST, " - " + msg, *args)
_test_logger.info(" - " + msg, *args)
datas = {}
if active_model:
@ -145,7 +147,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
raise ValueError('You cannot only specify action_id "%s" without a module name' % action_id)
act_module = our_module
act_xmlid = action_id
act_model, act_id = pool.get('ir.model.data').get_object_reference(cr, uid, act_module, act_xmlid)
act_model, act_id = registry['ir.model.data'].get_object_reference(cr, uid, act_module, act_xmlid)
else:
assert isinstance(action_id, (long, int))
act_model = 'ir.action.act_window' # assume that
@ -181,11 +183,11 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
log_test("will emulate a %s view: %s#%s",
action['view_type'], datas['res_model'], view_id or '?')
view_res = pool.get(datas['res_model']).fields_view_get(cr, uid, view_id, action['view_type'], context)
view_res = registry[datas['res_model']].fields_view_get(cr, uid, view_id, action['view_type'], context)
assert view_res and view_res.get('arch'), "Did not return any arch for the view"
view_data = {}
if view_res.get('fields',{}).keys():
view_data = pool.get(datas['res_model']).default_get(cr, uid, view_res['fields'].keys(), context)
view_data = registry[datas['res_model']].default_get(cr, uid, view_res['fields'].keys(), context)
if datas.get('form'):
view_data.update(datas.get('form'))
if wiz_data:
@ -238,7 +240,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
if not datas['res_id']:
# it is probably an orm_memory object, we need to create
# an instance
datas['res_id'] = pool.get(datas['res_model']).create(cr, uid, view_data, context)
datas['res_id'] = registry[datas['res_model']].create(cr, uid, view_data, context)
if not buttons:
raise AssertionError("view form doesn't have any buttons to press!")
@ -255,7 +257,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
continue
if b['type'] == 'object':
#there we are! press the button!
fn = getattr(pool.get(datas['res_model']), b['name'])
fn = getattr(registry[datas['res_model']], b['name'])
if not fn:
_logger.error("The %s model doesn't have a %s attribute!", datas['res_model'], b['name'])
continue
@ -281,7 +283,7 @@ def try_report_action(cr, uid, action_id, active_model=None, active_ids=None,
raise Exception("Cannot handle action of type %s" % act_model)
log_test("will be using %s action %s #%d", act_model, act_xmlid, act_id)
action = pool.get(act_model).read(cr, uid, act_id, context=context)
action = registry[act_model].read(cr, uid, act_id, context=context)
assert action, "Could not read action %s[%s]" %(act_model, act_id)
loop = 0
while action:

View File

@ -25,7 +25,6 @@ import fnmatch
import inspect
import locale
import os
import openerp.pooler as pooler
import openerp.sql_db as sql_db
import re
import logging
@ -43,6 +42,7 @@ import misc
from misc import UpdateableStr
from misc import SKIPPED_ELEMENT_TYPES
import osutil
import openerp
from openerp import SUPERUSER_ID
_logger = logging.getLogger(__name__)
@ -208,7 +208,7 @@ class GettextAlias(object):
(cr, dummy) = self._get_cr(frame, allow_create=False)
uid = self._get_uid(frame)
if pool and cr and uid:
lang = pool.get('res.users').context_get(cr, uid)['lang']
lang = pool['res.users'].context_get(cr, uid)['lang']
return lang
def __call__(self, source):
@ -227,8 +227,8 @@ class GettextAlias(object):
cr, is_new_cr = self._get_cr(frame)
if cr:
# Try to use ir.translation to benefit from global cache if possible
pool = pooler.get_pool(cr.dbname)
res = pool.get('ir.translation')._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source)
registry = openerp.registry(cr.dbname)
res = registry['ir.translation']._get_source(cr, SUPERUSER_ID, None, ('code','sql_constraint'), lang, source)
else:
_logger.debug('no context cursor detected, skipping translation for "%r"', source)
else:
@ -611,11 +611,11 @@ def babel_extract_qweb(fileobj, keywords, comment_tags, options):
def trans_generate(lang, modules, cr):
dbname = cr.dbname
pool = pooler.get_pool(dbname)
trans_obj = pool.get('ir.translation')
model_data_obj = pool.get('ir.model.data')
registry = openerp.registry(dbname)
trans_obj = registry.get('ir.translation')
model_data_obj = registry.get('ir.model.data')
uid = 1
l = pool.models.items()
l = registry.models.items()
l.sort()
query = 'SELECT name, model, res_id, module' \
@ -659,15 +659,15 @@ def trans_generate(lang, modules, cr):
model = encode(model)
xml_name = "%s.%s" % (module, encode(xml_name))
if not pool.get(model):
if not registry.get(model):
_logger.error("Unable to find object %r", model)
continue
exists = pool.get(model).exists(cr, uid, res_id)
exists = registry[model].exists(cr, uid, res_id)
if not exists:
_logger.warning("Unable to find object %r with id %d", model, res_id)
continue
obj = pool.get(model).browse(cr, uid, res_id)
obj = registry[model].browse(cr, uid, res_id)
if model=='ir.ui.view':
d = etree.XML(encode(obj.arch))
@ -682,7 +682,7 @@ def trans_generate(lang, modules, cr):
except AttributeError, exc:
_logger.error("name error in %s: %s", xml_name, str(exc))
continue
objmodel = pool.get(obj.model)
objmodel = registry[obj.model]
if not objmodel or not field_name in objmodel._columns:
continue
field_def = objmodel._columns[field_name]
@ -764,7 +764,7 @@ def trans_generate(lang, modules, cr):
push_constraint_msg(module, term_type, model._name, constraint[msg_pos])
for (_, model, module) in cr.fetchall():
model_obj = pool.get(model)
model_obj = registry.get(model)
if not model_obj:
_logger.error("Unable to find object %r", model)
@ -794,7 +794,7 @@ def trans_generate(lang, modules, cr):
return path.split(os.path.sep)[0]
return 'base' # files that are not in a module are considered as being in 'base' module
modobj = pool.get('ir.module.module')
modobj = registry['ir.module.module']
installed_modids = modobj.search(cr, uid, [('state', '=', 'installed')])
installed_modules = map(lambda m: m['name'], modobj.read(cr, uid, installed_modids, ['name']))
@ -887,9 +887,9 @@ def trans_load_data(cr, fileobj, fileformat, lang, lang_name=None, verbose=True,
if context is None:
context = {}
db_name = cr.dbname
pool = pooler.get_pool(db_name)
lang_obj = pool.get('res.lang')
trans_obj = pool.get('ir.translation')
registry = openerp.registry(db_name)
lang_obj = registry.get('res.lang')
trans_obj = registry.get('ir.translation')
iso_lang = misc.get_iso_codes(lang)
try:
ids = lang_obj.search(cr, SUPERUSER_ID, [('code','=', lang)])
@ -1009,11 +1009,10 @@ def load_language(cr, lang):
:param lang: language ISO code with optional _underscore_ and l10n flavor (ex: 'fr', 'fr_BE', but not 'fr-BE')
:type lang: str
"""
pool = pooler.get_pool(cr.dbname)
language_installer = pool.get('base.language.install')
uid = 1
oid = language_installer.create(cr, uid, {'lang': lang})
language_installer.lang_install(cr, uid, [oid], context=None)
registry = openerp.registry(cr.dbname)
language_installer = registry['base.language.install']
oid = language_installer.create(cr, SUPERUSER_ID, {'lang': lang})
language_installer.lang_install(cr, SUPERUSER_ID, [oid], context=None)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -5,8 +5,9 @@ import time # used to eval time.strftime expressions
from datetime import datetime, timedelta
import logging
import openerp.pooler as pooler
import openerp
import openerp.sql_db as sql_db
import openerp.workflow
import misc
from config import config
import yaml_tag
@ -112,7 +113,7 @@ class YamlInterpreter(object):
self.assertion_report = report
self.noupdate = noupdate
self.loglevel = loglevel
self.pool = pooler.get_pool(cr.dbname)
self.pool = openerp.registry(cr.dbname)
self.uid = 1
self.context = {} # opererp context
self.eval_context = {'ref': self._ref(),
@ -128,9 +129,7 @@ class YamlInterpreter(object):
return lambda xml_id: self.get_id(xml_id)
def get_model(self, model_name):
model = self.pool.get(model_name)
assert model, "The model %s does not exist." % (model_name,)
return model
return self.pool[model_name]
def validate_xml_id(self, xml_id):
id = xml_id
@ -140,7 +139,7 @@ class YamlInterpreter(object):
"It is used to refer to other modules ID, in the form: module.record_id" \
% (xml_id,)
if module != self.module:
module_count = self.pool.get('ir.module.module').search_count(self.cr, self.uid, \
module_count = self.pool['ir.module.module'].search_count(self.cr, self.uid, \
['&', ('name', '=', module), ('state', 'in', ['installed'])])
assert module_count == 1, 'The ID "%s" refers to an uninstalled module.' % (xml_id,)
if len(id) > 64: # TODO where does 64 come from (DB is 128)? should be a constant or loaded form DB
@ -162,7 +161,7 @@ class YamlInterpreter(object):
module = self.module
checked_xml_id = xml_id
try:
_, id = self.pool.get('ir.model.data').get_object_reference(self.cr, self.uid, module, checked_xml_id)
_, id = self.pool['ir.model.data'].get_object_reference(self.cr, self.uid, module, checked_xml_id)
self.id_map[xml_id] = id
except ValueError:
raise ValueError("""%s not found when processing %s.
@ -201,7 +200,7 @@ class YamlInterpreter(object):
ids = [self.get_id(assertion.id)]
elif assertion.search:
q = eval(assertion.search, self.eval_context)
ids = self.pool.get(assertion.model).search(self.cr, self.uid, q, context=assertion.context)
ids = self.pool[assertion.model].search(self.cr, self.uid, q, context=assertion.context)
else:
raise YamlImportException('Nothing to assert: you must give either an id or a search criteria.')
return ids
@ -281,7 +280,6 @@ class YamlInterpreter(object):
return record_dict
def process_record(self, node):
import openerp.osv as osv
record, fields = node.items()[0]
model = self.get_model(record.model)
@ -290,20 +288,20 @@ class YamlInterpreter(object):
module = self.module
if '.' in view_id:
module, view_id = view_id.split('.',1)
view_id = self.pool.get('ir.model.data').get_object_reference(self.cr, SUPERUSER_ID, module, view_id)[1]
view_id = self.pool['ir.model.data'].get_object_reference(self.cr, SUPERUSER_ID, module, view_id)[1]
if model.is_transient():
record_dict=self.create_osv_memory_record(record, fields)
else:
self.validate_xml_id(record.id)
try:
self.pool.get('ir.model.data')._get_id(self.cr, SUPERUSER_ID, self.module, record.id)
self.pool['ir.model.data']._get_id(self.cr, SUPERUSER_ID, self.module, record.id)
default = False
except ValueError:
default = True
if self.isnoupdate(record) and self.mode != 'init':
id = self.pool.get('ir.model.data')._update_dummy(self.cr, SUPERUSER_ID, record.model, self.module, record.id)
id = self.pool['ir.model.data']._update_dummy(self.cr, SUPERUSER_ID, record.model, self.module, record.id)
# check if the resource already existed at the last update
if id:
self.id_map[record] = int(id)
@ -324,7 +322,7 @@ class YamlInterpreter(object):
record_dict = self._create_record(model, fields, view_info, default=default)
_logger.debug("RECORD_DICT %s" % record_dict)
id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, record.model, \
id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, record.model, \
self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context)
self.id_map[record.id] = int(id)
if config.get('import_partial'):
@ -346,7 +344,7 @@ class YamlInterpreter(object):
one2many_view = fg[field_name]['views'].get(view_type)
# if the view is not defined inline, we call fields_view_get()
if not one2many_view:
one2many_view = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, SUPERUSER_ID, False, view_type, self.context)
one2many_view = self.pool[fg[field_name]['relation']].fields_view_get(self.cr, SUPERUSER_ID, False, view_type, self.context)
return one2many_view
def process_val(key, val):
@ -543,7 +541,14 @@ class YamlInterpreter(object):
python, statements = node.items()[0]
model = self.get_model(python.model)
statements = statements.replace("\r\n", "\n")
code_context = { 'model': model, 'cr': self.cr, 'uid': self.uid, 'log': self._log, 'context': self.context }
code_context = {
'model': model,
'cr': self.cr,
'uid': self.uid,
'log': self._log,
'context': self.context,
'openerp': openerp,
}
code_context.update({'self': model}) # remove me when no !python block test uses 'self' anymore
try:
code_obj = compile(statements, self.filename, 'exec')
@ -584,9 +589,7 @@ class YamlInterpreter(object):
signals=[x['signal'] for x in self.cr.dictfetchall()]
if workflow.action not in signals:
raise YamlImportException('Incorrect action %s. No such action defined' % workflow.action)
import openerp.netsvc as netsvc
wf_service = netsvc.LocalService("workflow")
wf_service.trg_validate(uid, workflow.model, id, workflow.action, self.cr)
openerp.workflow.trg_validate(uid, workflow.model, id, workflow.action, self.cr)
def _eval_params(self, model, params):
args = []
@ -707,7 +710,7 @@ class YamlInterpreter(object):
self._set_group_values(node, values)
pid = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \
pid = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \
'ir.ui.menu', self.module, values, node.id, mode=self.mode, \
noupdate=self.isnoupdate(node), res_id=res and res[0] or False)
@ -718,7 +721,7 @@ class YamlInterpreter(object):
action_type = node.type or 'act_window'
action_id = self.get_id(node.action)
action = "ir.actions.%s,%d" % (action_type, action_id)
self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \
self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \
'tree_but_open', 'Menuitem', [('ir.ui.menu', int(parent_id))], action, True, True, xml_id=node.id)
def process_act_window(self, node):
@ -752,7 +755,7 @@ class YamlInterpreter(object):
if node.target:
values['target'] = node.target
id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \
id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \
'ir.actions.act_window', self.module, values, node.id, mode=self.mode)
self.id_map[node.id] = int(id)
@ -760,7 +763,7 @@ class YamlInterpreter(object):
keyword = 'client_action_relate'
value = 'ir.actions.act_window,%s' % id
replace = node.replace or True
self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', keyword, \
self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', keyword, \
node.id, [node.src_model], value, replace=replace, noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id)
# TODO add remove ir.model.data
@ -768,11 +771,11 @@ class YamlInterpreter(object):
assert getattr(node, 'model'), "Attribute %s of delete tag is empty !" % ('model',)
if self.pool.get(node.model):
if node.search:
ids = self.pool.get(node.model).search(self.cr, self.uid, eval(node.search, self.eval_context))
ids = self.pool[node.model].search(self.cr, self.uid, eval(node.search, self.eval_context))
else:
ids = [self.get_id(node.id)]
if len(ids):
self.pool.get(node.model).unlink(self.cr, self.uid, ids)
self.pool[node.model].unlink(self.cr, self.uid, ids)
else:
self._log("Record not deleted.")
@ -781,7 +784,7 @@ class YamlInterpreter(object):
res = {'name': node.name, 'url': node.url, 'target': node.target}
id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, \
id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, \
"ir.actions.act_url", self.module, res, node.id, mode=self.mode)
self.id_map[node.id] = int(id)
# ir_set
@ -789,7 +792,7 @@ class YamlInterpreter(object):
keyword = node.keyword or 'client_action_multi'
value = 'ir.actions.act_url,%s' % id
replace = node.replace or True
self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \
self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \
keyword, node.url, ["ir.actions.act_url"], value, replace=replace, \
noupdate=self.isnoupdate(node), isobject=True, xml_id=node.id)
@ -804,7 +807,7 @@ class YamlInterpreter(object):
else:
value = expression
res[fieldname] = value
self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, res['key'], res['key2'], \
self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, res['key'], res['key2'], \
res['name'], res['models'], res['value'], replace=res.get('replace',True), \
isobject=res.get('isobject', False), meta=res.get('meta',None))
@ -833,7 +836,7 @@ class YamlInterpreter(object):
self._set_group_values(node, values)
id = self.pool.get('ir.model.data')._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \
id = self.pool['ir.model.data']._update(self.cr, SUPERUSER_ID, "ir.actions.report.xml", \
self.module, values, xml_id, noupdate=self.isnoupdate(node), mode=self.mode)
self.id_map[xml_id] = int(id)
@ -841,7 +844,7 @@ class YamlInterpreter(object):
keyword = node.keyword or 'client_print_multi'
value = 'ir.actions.report.xml,%s' % id
replace = node.replace or True
self.pool.get('ir.model.data').ir_set(self.cr, SUPERUSER_ID, 'action', \
self.pool['ir.model.data'].ir_set(self.cr, SUPERUSER_ID, 'action', \
keyword, values['name'], [values['model']], value, replace=replace, isobject=True, xml_id=xml_id)
def process_none(self):
@ -922,7 +925,7 @@ class YamlInterpreter(object):
def yaml_import(cr, module, yamlfile, kind, idref=None, mode='init', noupdate=False, report=None):
if idref is None:
idref = {}
loglevel = logging.TEST if kind == 'test' else logging.DEBUG
loglevel = logging.INFO if kind == 'test' else logging.DEBUG
yaml_string = yamlfile.read()
yaml_interpreter = YamlInterpreter(cr, module, idref, mode, filename=yamlfile.name, report=report, noupdate=noupdate, loglevel=loglevel)
yaml_interpreter.process(yaml_string)

View File

@ -1,28 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
class except_wkf(Exception):
def __init__(self, name, value):
self.name = name
self.value = value
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -19,7 +19,7 @@
#
##############################################################################
import openerp.pooler as pooler
import openerp
from openerp.tools.safe_eval import safe_eval as eval
class Env(dict):
@ -28,7 +28,7 @@ class Env(dict):
self.uid = uid
self.model = model
self.ids = ids
self.obj = pooler.get_pool(cr.dbname).get(model)
self.obj = openerp.registry(cr.dbname)[model]
self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def __getitem__(self, key):
@ -58,7 +58,7 @@ def _eval_expr(cr, ident, workitem, action):
return ret
def execute_action(cr, ident, workitem, activity):
obj = pooler.get_pool(cr.dbname).get('ir.actions.server')
obj = openerp.registry(cr.dbname)['ir.actions.server']
ctx = {'active_model':ident[1], 'active_id':ident[2], 'active_ids':[ident[2]]}
result = obj.run(cr, ident[0], [activity['action_id']], ctx)
return result
@ -72,8 +72,8 @@ def check(cr, workitem, ident, transition, signal):
uid = ident[0]
if transition['group_id'] and uid != 1:
pool = pooler.get_pool(cr.dbname)
user_groups = pool.get('res.users').read(cr, uid, [uid], ['groups_id'])[0]['groups_id']
registry = openerp.registry(cr.dbname)
user_groups = registry['res.users'].read(cr, uid, [uid], ['groups_id'])[0]['groups_id']
if not transition['group_id'] in user_groups:
return False

View File

@ -1,39 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
#
# May be uncommented to logs workflows modifications
#
def log(cr,ident,act_id,info=''):
return
# msg = """
#res_type: %r
#res_id: %d
#uid: %d
#act_id: %d
#info: %s
#""" % (ident[1], ident[2], ident[0], act_id, info)
#cr.execute('insert into wkf_logs (res_type, res_id, uid, act_id, time, info) values (%s,%s,%s,%s,current_time,%s)', (ident[1],int(ident[2]),int(ident[0]),int(act_id),info))
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -23,11 +23,13 @@
# TODO:
# cr.execute('delete from wkf_triggers where model=%s and res_id=%s', (res_type,res_id))
#
import logging
import instance
import wkf_expr
import wkf_logs
logger = logging.getLogger(__name__)
def create(cr, act_datas, inst_id, ident, stack):
for act in act_datas:
@ -36,34 +38,29 @@ def create(cr, act_datas, inst_id, ident, stack):
cr.execute("insert into wkf_workitem (id,act_id,inst_id,state) values (%s,%s,%s,'active')", (id_new, act['id'], inst_id))
cr.execute('select * from wkf_workitem where id=%s',(id_new,))
res = cr.dictfetchone()
wkf_logs.log(cr,ident,act['id'],'active')
logger.info('Created workflow item in activity %s',
act['id'], extra={'ident': ident})
process(cr, res, ident, stack=stack)
def process(cr, workitem, ident, signal=None, force_running=False, stack=None):
if stack is None:
raise 'Error !!!'
result = True
assert stack is not None
cr.execute('select * from wkf_activity where id=%s', (workitem['act_id'],))
activity = cr.dictfetchone()
triggers = False
if workitem['state']=='active':
if workitem['state'] == 'active':
triggers = True
result = _execute(cr, workitem, activity, ident, stack)
if not result:
if not _execute(cr, workitem, activity, ident, stack):
return False
if workitem['state']=='running':
pass
if workitem['state']=='complete' or force_running:
if force_running or workitem['state'] == 'complete':
ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
triggers = triggers and not ok
if triggers:
cr.execute('select * from wkf_transition where act_from=%s', (workitem['act_id'],))
alltrans = cr.dictfetchall()
for trans in alltrans:
for trans in cr.dictfetchall():
if trans['trigger_model']:
ids = wkf_expr._eval_expr(cr,ident,workitem,trans['trigger_expr_id'])
for res_id in ids:
@ -71,7 +68,7 @@ def process(cr, workitem, ident, signal=None, force_running=False, stack=None):
id =cr.fetchone()[0]
cr.execute('insert into wkf_triggers (model,res_id,instance_id,workitem_id,id) values (%s,%s,%s,%s,%s)', (trans['trigger_model'],res_id,workitem['inst_id'], workitem['id'], id))
return result
return True
# ---------------------- PRIVATE FUNCS --------------------------------
@ -79,7 +76,8 @@ def process(cr, workitem, ident, signal=None, force_running=False, stack=None):
def _state_set(cr, workitem, activity, state, ident):
cr.execute('update wkf_workitem set state=%s where id=%s', (state,workitem['id']))
workitem['state'] = state
wkf_logs.log(cr,ident,activity['id'],state)
logger.info("Changed state of work item %s to \"%s\" in activity %s",
workitem['id'], state, activity['id'], extra={'ident': ident})
def _execute(cr, workitem, activity, ident, stack):
result = True
@ -146,8 +144,6 @@ def _execute(cr, workitem, activity, ident, stack):
return result
def _split_test(cr, workitem, split_mode, ident, signal=None, stack=None):
if stack is None:
raise 'Error !!!'
cr.execute('select * from wkf_transition where act_from=%s', (workitem['act_id'],))
test = False
transitions = []

View File

@ -47,7 +47,7 @@ def run(args):
config = openerp.tools.config
if args.tests:
config['log_handler'] = [':TEST']
config['log_handler'] = [':INFO']
config['test_enable'] = True
config['without_demo'] = False
else: