[MERGE] latest trunk
bzr revid: odo@openerp.com-20110908113641-xai86jar2fkbwdm7
This commit is contained in:
+5
-1
@@ -252,6 +252,11 @@ if __name__ == "__main__":
|
||||
import_translation()
|
||||
sys.exit(0)
|
||||
|
||||
if not config["stop_after_init"]:
|
||||
# Some module register themselves when they are loaded so we need the
|
||||
# services to be running before loading any registry.
|
||||
start_services()
|
||||
|
||||
if config['db_name']:
|
||||
for dbname in config['db_name'].split(','):
|
||||
preload_registry(dbname)
|
||||
@@ -261,7 +266,6 @@ if __name__ == "__main__":
|
||||
|
||||
setup_pid_file()
|
||||
setup_signal_handlers()
|
||||
start_services()
|
||||
logger = logging.getLogger('server')
|
||||
logger.info('OpenERP server is running, waiting for connections...')
|
||||
quit_on_signals()
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
<field name="view_id" ref="sequence_view_tree"/>
|
||||
<field name="context">{'active_test': False}</field>
|
||||
</record>
|
||||
<menuitem id="next_id_5" name="Sequences" parent="base.menu_config"/>
|
||||
<menuitem id="next_id_5" name="Sequences & Identifiers" parent="base.menu_config"/>
|
||||
<menuitem action="ir_sequence_form" id="menu_ir_sequence_form" parent="next_id_5"/>
|
||||
|
||||
<!-- Sequences Types -->
|
||||
@@ -1198,7 +1198,7 @@
|
||||
<field name="model">ir.model.data</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Object Identifiers">
|
||||
<form string="External Identifiers">
|
||||
<field name="name"/>
|
||||
<field name="module"/>
|
||||
<field name="model"/>
|
||||
@@ -1216,7 +1216,7 @@
|
||||
<field name="model">ir.model.data</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Object Identifiers">
|
||||
<tree string="External Identifiers">
|
||||
<field name="module"/>
|
||||
<field name="name"/>
|
||||
<field name="model"/>
|
||||
@@ -1230,7 +1230,7 @@
|
||||
<field name="model">ir.model.data</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Object Identifiers">
|
||||
<search string="External Identifiers">
|
||||
<filter icon="terp-camera_test"
|
||||
string="Updatable"
|
||||
domain="[('noupdate', '=', False)]"/>
|
||||
@@ -1270,7 +1270,7 @@
|
||||
<menuitem action="action_model_fields" id="ir_model_model_fields" parent="base.next_id_9"/>
|
||||
|
||||
<record id="action_model_data" model="ir.actions.act_window">
|
||||
<field name="name">Object Identifiers</field>
|
||||
<field name="name">External Identifiers</field>
|
||||
<field name="res_model">ir.model.data</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_model_data_list"/>
|
||||
|
||||
@@ -561,14 +561,27 @@ class ir_model_access(osv.osv):
|
||||
ir_model_access()
|
||||
|
||||
class ir_model_data(osv.osv):
|
||||
"""Holds external identifier keys for records in the database.
|
||||
This has two main uses:
|
||||
|
||||
* allows easy data integration with third-party systems,
|
||||
making import/export/sync of data possible, as records
|
||||
can be uniquely identified across multiple systems
|
||||
* allows tracking the origin of data installed by OpenERP
|
||||
modules themselves, thus making it possible to later
|
||||
update them seamlessly.
|
||||
"""
|
||||
_name = 'ir.model.data'
|
||||
__logger = logging.getLogger('addons.base.'+_name)
|
||||
_order = 'module,model,name'
|
||||
_columns = {
|
||||
'name': fields.char('XML Identifier', required=True, size=128, select=1),
|
||||
'model': fields.char('Object', required=True, size=64, select=1),
|
||||
'name': fields.char('External Identifier', required=True, size=128, select=1,
|
||||
help="External Key/Identifier that can be used for "
|
||||
"data integration with third-party systems"),
|
||||
'model': fields.char('Model Name', required=True, size=64, select=1),
|
||||
'module': fields.char('Module', required=True, size=64, select=1),
|
||||
'res_id': fields.integer('Resource ID', select=1),
|
||||
'res_id': fields.integer('Record ID', select=1,
|
||||
help="ID of the target record in the database"),
|
||||
'noupdate': fields.boolean('Non Updatable'),
|
||||
'date_update': fields.datetime('Update Date'),
|
||||
'date_init': fields.datetime('Init Date')
|
||||
@@ -580,7 +593,7 @@ class ir_model_data(osv.osv):
|
||||
'module': ''
|
||||
}
|
||||
_sql_constraints = [
|
||||
('module_name_uniq', 'unique(name, module)', 'You cannot have multiple records with the same id for the same module !'),
|
||||
('module_name_uniq', 'unique(name, module)', 'You cannot have multiple records with the same external ID in the same module!'),
|
||||
]
|
||||
|
||||
def __init__(self, pool, cr):
|
||||
|
||||
@@ -59,7 +59,7 @@ class ir_translation(osv.osv):
|
||||
# These two columns map to ir_model_data.module and ir_model_data.name.
|
||||
# They are used to resolve the res_id above after loading is done.
|
||||
'module': fields.char('Module', size=64, help='Maps to the ir_model_data for which this translation is provided.'),
|
||||
'xml_id': fields.char('XML Id', size=128, help='Maps to the ir_model_data for which this translation is provided.'),
|
||||
'xml_id': fields.char('External ID', size=128, help='Maps to the ir_model_data for which this translation is provided.'),
|
||||
}
|
||||
|
||||
def _auto_init(self, cr, context={}):
|
||||
|
||||
@@ -73,11 +73,12 @@ class view(osv.osv):
|
||||
('calendar', 'Calendar'),
|
||||
('diagram','Diagram'),
|
||||
('gantt', 'Gantt'),
|
||||
('kanban', 'Kanban'),
|
||||
('search','Search')), 'View Type', required=True, select=True),
|
||||
'arch': fields.text('View Architecture', required=True),
|
||||
'inherit_id': fields.many2one('ir.ui.view', 'Inherited View', ondelete='cascade', select=True),
|
||||
'field_parent': fields.char('Child Field',size=64),
|
||||
'xml_id': fields.function(osv.osv.get_xml_id, type='char', size=128, string="XML ID",
|
||||
'xml_id': fields.function(osv.osv.get_xml_id, type='char', size=128, string="External ID",
|
||||
method=True, help="ID of the view defined in xml file"),
|
||||
}
|
||||
_defaults = {
|
||||
|
||||
@@ -111,6 +111,19 @@
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="kanban">
|
||||
<rng:element name="kanban">
|
||||
<rng:zeroOrMore>
|
||||
<rng:ref name="field"/>
|
||||
</rng:zeroOrMore>
|
||||
<rng:element name="templates">
|
||||
<rng:oneOrMore>
|
||||
<rng:ref name="any"/>
|
||||
</rng:oneOrMore>
|
||||
</rng:element>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
<rng:define name="tree">
|
||||
<rng:element name="tree">
|
||||
<rng:ref name="overload"/>
|
||||
@@ -460,6 +473,7 @@
|
||||
<rng:zeroOrMore>
|
||||
<rng:choice>
|
||||
<rng:ref name="diagram"/>
|
||||
<rng:ref name="kanban"/>
|
||||
<rng:ref name="form"/>
|
||||
<rng:ref name="data"/>
|
||||
<rng:ref name="tree"/>
|
||||
@@ -618,6 +632,7 @@
|
||||
<rng:start>
|
||||
<rng:choice>
|
||||
<rng:ref name="diagram" />
|
||||
<rng:ref name="kanban" />
|
||||
<rng:ref name="form" />
|
||||
<rng:ref name="search" />
|
||||
<rng:ref name="group" />
|
||||
|
||||
+28
-19
@@ -32,7 +32,9 @@
|
||||
* size
|
||||
"""
|
||||
|
||||
import base64
|
||||
import datetime as DT
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import warnings
|
||||
@@ -727,34 +729,41 @@ def get_nice_size(value):
|
||||
size = len(value)
|
||||
return tools.human_size(size)
|
||||
|
||||
# See http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
|
||||
# and http://bugs.python.org/issue10066
|
||||
invalid_xml_low_bytes = re.compile(r'[\x00-\x08\x0b-\x0c\x0e-\x1f]')
|
||||
|
||||
def sanitize_binary_value(value):
|
||||
# binary fields should be 7-bit ASCII base64-encoded data,
|
||||
# but we do additional sanity checks to make sure the values
|
||||
# are not something else that won't pass via xmlrpc
|
||||
# are not something else that won't pass via XML-RPC
|
||||
if isinstance(value, (xmlrpclib.Binary, tuple, list, dict)):
|
||||
# these builtin types are meant to pass untouched
|
||||
return value
|
||||
|
||||
# For all other cases, handle the value as a binary string:
|
||||
# it could be a 7-bit ASCII string (e.g base64 data), but also
|
||||
# any 8-bit content from files, with byte values that cannot
|
||||
# be passed inside XML!
|
||||
# See for more info:
|
||||
# Handle invalid bytes values that will cause problems
|
||||
# for XML-RPC. See for more info:
|
||||
# - http://bugs.python.org/issue10066
|
||||
# - http://www.w3.org/TR/2000/REC-xml-20001006#NT-Char
|
||||
#
|
||||
# One solution is to convert the byte-string to unicode,
|
||||
# so it gets serialized as utf-8 encoded data (always valid XML)
|
||||
# If invalid XML byte values were present, tools.ustr() uses
|
||||
# the Latin-1 codec as fallback, which converts any 8-bit
|
||||
# byte value, resulting in valid utf-8-encoded bytes
|
||||
# in the end:
|
||||
# >>> unicode('\xe1','latin1').encode('utf8') == '\xc3\xa1'
|
||||
# Note: when this happens, decoding on the other endpoint
|
||||
# is not likely to produce the expected output, but this is
|
||||
# just a safety mechanism (in these cases base64 data or
|
||||
# xmlrpc.Binary values should be used instead)
|
||||
return tools.ustr(value)
|
||||
|
||||
# Coercing to unicode would normally allow it to properly pass via
|
||||
# XML-RPC, transparently encoded as UTF-8 by xmlrpclib.
|
||||
# (this works for _any_ byte values, thanks to the fallback
|
||||
# to latin-1 passthrough encoding when decoding to unicode)
|
||||
value = tools.ustr(value)
|
||||
|
||||
# Due to Python bug #10066 this could still yield invalid XML
|
||||
# bytes, specifically in the low byte range, that will crash
|
||||
# the decoding side: [\x00-\x08\x0b-\x0c\x0e-\x1f]
|
||||
# So check for low bytes values, and if any, perform
|
||||
# base64 encoding - not very smart or useful, but this is
|
||||
# our last resort to avoid crashing the request.
|
||||
if invalid_xml_low_bytes.search(value):
|
||||
# b64-encode after restoring the pure bytes with latin-1
|
||||
# passthrough encoding
|
||||
value = base64.b64encode(value.encode('latin-1'))
|
||||
|
||||
return value
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user