[BACKPORT] Stable fixes and refactorings to Trunk
bzr revid: jvo@tinyerp.com-20100520063044-sviy1e9pybirhpsw
This commit is contained in:
commit
e3ccef27d3
|
@ -9,7 +9,8 @@ include bin/server.pkey
|
|||
include bin/gpl.txt
|
||||
include man/openerp-server.1
|
||||
include man/openerp_serverrc.5
|
||||
recursive-include pixmaps
|
||||
recursive-include pixmaps *
|
||||
recursive-include win32 *
|
||||
recursive-include doc *
|
||||
recursive-include bin *xml *xsl *sql *rml *sxw *csv *rng
|
||||
graft bin/addons/
|
||||
|
|
|
@ -1302,14 +1302,14 @@
|
|||
<field name="subject" colspan="4" attrs="{'required':[('state','=','email')]}"/>
|
||||
<field name="message" select="2" colspan="4" attrs="{'required':[('state','=','email')]}"/>
|
||||
<newline/>
|
||||
<label colspan="4" string="Access all the fields related to the current object using expression in double brackets, i.e.[[ object.partner_id.name ]]" align="0.0"/>
|
||||
<label colspan="4" string="Access all the fields related to the current object using expressions, i.e. object.partner_id.name " align="0.0"/>
|
||||
</page>
|
||||
<page string="SMS Configuration" attrs="{'invisible':[('state','!=','sms')]}">
|
||||
<separator colspan="4" string="SMS Configuration"/>
|
||||
<field name="mobile" domain="[('model_id','=',model_id)]" attrs="{'required':[('state','=','sms')]}"/>
|
||||
<field name="sms" colspan="4" attrs="{'required':[('state','=','sms')]}"/>
|
||||
<newline/>
|
||||
<label colspan="4" string="Access all the fields related to the current object using expression in double brackets, i.e. [[ object.partner_id.name ]]" align="0.0"/>
|
||||
<label colspan="4" string="Access all the fields related to the current object using expressions, i.e. object.partner_id.name " align="0.0"/>
|
||||
</page>
|
||||
<page string="Create / Write / Copy" attrs="{'invisible':[('state','!=','object_create'), ('state','!=','object_write'), ('state','!=','object_copy')]}">
|
||||
<separator colspan="4" string="Fields Mapping"/>
|
||||
|
|
|
@ -455,7 +455,7 @@ class actions_server(osv.osv):
|
|||
'type': lambda *a: 'ir.actions.server',
|
||||
'sequence': lambda *a: 5,
|
||||
'code': lambda *a: """# You can use the following variables
|
||||
# - object
|
||||
# - object or obj
|
||||
# - time
|
||||
# - cr
|
||||
# - uid
|
||||
|
@ -532,7 +532,6 @@ class actions_server(osv.osv):
|
|||
|
||||
def run(self, cr, uid, ids, context={}):
|
||||
logger = netsvc.Logger()
|
||||
|
||||
for action in self.browse(cr, uid, ids, context):
|
||||
obj_pool = self.pool.get(action.model_id.model)
|
||||
obj = obj_pool.browse(cr, uid, context['active_id'], context=context)
|
||||
|
@ -554,19 +553,26 @@ class actions_server(osv.osv):
|
|||
return self.pool.get(action.action_id.type)\
|
||||
.read(cr, uid, action.action_id.id, context=context)
|
||||
|
||||
if action.state == 'code':
|
||||
localdict = {
|
||||
'self': self.pool.get(action.model_id.model),
|
||||
'context': context,
|
||||
'time': time,
|
||||
'ids': ids,
|
||||
'cr': cr,
|
||||
'uid': uid,
|
||||
'object':obj
|
||||
}
|
||||
exec action.code in localdict
|
||||
if 'action' in localdict:
|
||||
return localdict['action']
|
||||
if config['server_actions_allow_code']:
|
||||
localdict = {
|
||||
'self': self.pool.get(action.model_id.model),
|
||||
'context': context,
|
||||
'time': time,
|
||||
'ids': ids,
|
||||
'cr': cr,
|
||||
'uid': uid,
|
||||
'object':obj,
|
||||
'obj': obj,
|
||||
}
|
||||
exec action.code in localdict
|
||||
if 'action' in localdict:
|
||||
return localdict['action']
|
||||
else:
|
||||
netsvc.Logger().notifyChannel(
|
||||
self._name, netsvc.LOG_ERROR,
|
||||
"%s is a `code` server action, but "
|
||||
"it isn't allowed in this configuration.\n\n"
|
||||
"See server options to enable it"%action)
|
||||
|
||||
if action.state == 'email':
|
||||
user = config['email_from']
|
||||
|
@ -580,7 +586,7 @@ class actions_server(osv.osv):
|
|||
logger.notifyChannel('email', netsvc.LOG_INFO, 'Partner Email address not Specified!')
|
||||
continue
|
||||
if not user:
|
||||
raise osv.except_osv(_('Error'), _("Please specify server option --smtp-from !"))
|
||||
raise osv.except_osv(_('Error'), _("Please specify server option --email-from !"))
|
||||
|
||||
subject = self.merge_message(cr, uid, action.subject, action, context)
|
||||
body = self.merge_message(cr, uid, action.message, action, context)
|
||||
|
|
|
@ -146,16 +146,19 @@ class ir_cron(osv.osv, netsvc.Agent):
|
|||
def create(self, cr, uid, vals, context=None):
|
||||
res = super(ir_cron, self).create(cr, uid, vals, context=context)
|
||||
cr.commit()
|
||||
self.cancel(cr.dbname)
|
||||
self._poolJobs(cr.dbname)
|
||||
return res
|
||||
def write(self, cr, user, ids, vals, context=None):
|
||||
res = super(ir_cron, self).write(cr, user, ids, vals, context=context)
|
||||
cr.commit()
|
||||
self.cancel(cr.dbname)
|
||||
self._poolJobs(cr.dbname)
|
||||
return res
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
res = super(ir_cron, self).unlink(cr, uid, ids, context=context)
|
||||
cr.commit()
|
||||
self.cancel(cr.dbname)
|
||||
self._poolJobs(cr.dbname)
|
||||
return res
|
||||
ir_cron()
|
||||
|
|
|
@ -82,6 +82,8 @@ class ir_model(osv.osv):
|
|||
return super(ir_model,self).write(cr, user, ids, vals, context)
|
||||
|
||||
def create(self, cr, user, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
if context and context.get('manual',False):
|
||||
vals['state']='manual'
|
||||
res = super(ir_model,self).create(cr, user, vals, context)
|
||||
|
@ -260,6 +262,8 @@ class ir_model_fields(osv.osv):
|
|||
if 'model_id' in vals:
|
||||
model_data = self.pool.get('ir.model').browse(cr, user, vals['model_id'])
|
||||
vals['model'] = model_data.model
|
||||
if context is None:
|
||||
context = {}
|
||||
if context and context.get('manual',False):
|
||||
vals['state'] = 'manual'
|
||||
res = super(ir_model_fields,self).create(cr, user, vals, context)
|
||||
|
@ -267,7 +271,7 @@ 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 'relation' in vals and not self.pool.get('ir.model').search(cr, user, [('model','=',vals['relation'])]):
|
||||
if vals.get('relation',False) and not self.pool.get('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']):
|
||||
|
@ -286,7 +290,7 @@ class ir_model_access(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True),
|
||||
'model_id': fields.many2one('ir.model', 'Object', required=True),
|
||||
'group_id': fields.many2one('res.groups', 'Group'),
|
||||
'group_id': fields.many2one('res.groups', 'Group', ondelete='cascade'),
|
||||
'perm_read': fields.boolean('Read Access'),
|
||||
'perm_write': fields.boolean('Write Access'),
|
||||
'perm_create': fields.boolean('Create Access'),
|
||||
|
@ -453,7 +457,7 @@ class ir_model_data(osv.osv):
|
|||
def _get_id(self, cr, uid, module, xml_id):
|
||||
ids = self.search(cr, uid, [('module','=',module),('name','=', xml_id)])
|
||||
if not ids:
|
||||
raise Exception('No references to %s.%s' % (module, xml_id))
|
||||
raise ValueError('No references to %s.%s' % (module, xml_id))
|
||||
# the sql constraints ensure us we have only one result
|
||||
return ids[0]
|
||||
|
||||
|
|
|
@ -150,8 +150,8 @@ class ir_translation(osv.osv):
|
|||
if not context:
|
||||
context = {}
|
||||
ids = super(ir_translation, self).create(cursor, user, vals, context=context)
|
||||
for trans_obj in self.read(cursor, user, [ids], ['name','type','res_id'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
|
||||
for trans_obj in self.read(cursor, user, [ids], ['name','type','res_id','src','lang'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
|
||||
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
|
||||
return ids
|
||||
|
||||
|
@ -159,16 +159,16 @@ class ir_translation(osv.osv):
|
|||
if not context:
|
||||
context = {}
|
||||
result = super(ir_translation, self).write(cursor, user, ids, vals, context=context)
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
|
||||
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
|
||||
return result
|
||||
|
||||
def unlink(self, cursor, user, ids, context=None):
|
||||
if not context:
|
||||
context = {}
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], lang=context.get('lang','en_US'))
|
||||
for trans_obj in self.read(cursor, user, ids, ['name','type','res_id','src','lang'], context=context):
|
||||
self._get_source.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], trans_obj['lang'], source=trans_obj['src'])
|
||||
self._get_ids.clear_cache(cursor.dbname, user, trans_obj['name'], trans_obj['type'], context.get('lang','en_US'), [trans_obj['res_id']])
|
||||
result = super(ir_translation, self).unlink(cursor, user, ids, context=context)
|
||||
return result
|
||||
|
|
|
@ -31,6 +31,10 @@ def one_in(setA, setB):
|
|||
return True
|
||||
return False
|
||||
|
||||
def cond(C, X, Y):
|
||||
if C: return X
|
||||
return Y
|
||||
|
||||
class many2many_unique(fields.many2many):
|
||||
def set(self, cr, obj, id, name, values, user=None, context=None):
|
||||
if not values:
|
||||
|
@ -63,19 +67,24 @@ class ir_ui_menu(osv.osv):
|
|||
# radical but this doesn't frequently happen
|
||||
self._cache = {}
|
||||
|
||||
def search(self, cr, uid, args, offset=0, limit=2000, order=None,
|
||||
context=None, count=False):
|
||||
if context is None:
|
||||
context = {}
|
||||
ids = osv.orm.orm.search(self, cr, uid, args, offset, limit, order, context=context, count=(count and uid==1))
|
||||
def search(self, cr, uid, args, offset=0, limit=None, order=None,
|
||||
context=None, count=False):
|
||||
|
||||
super_offset = cond(uid == 1, offset, 0)
|
||||
super_limit = cond(uid == 1, limit, None)
|
||||
super_count = cond(uid == 1, count, False)
|
||||
|
||||
ids = super(ir_ui_menu, self).search(cr, uid, args, super_offset,
|
||||
super_limit, order,
|
||||
context=context, count=super_count)
|
||||
if uid == 1 or count:
|
||||
return ids
|
||||
|
||||
if not ids:
|
||||
if count:
|
||||
return 0
|
||||
return []
|
||||
|
||||
if count and ids:
|
||||
return ids
|
||||
|
||||
modelaccess = self.pool.get('ir.model.access')
|
||||
user_groups = set(self.pool.get('res.users').read(cr, 1, uid, ['groups_id'])['groups_id'])
|
||||
|
@ -123,6 +132,11 @@ class ir_ui_menu(osv.osv):
|
|||
result.append(menu.id)
|
||||
self._cache[key] = True
|
||||
|
||||
if offset:
|
||||
result = result[long(offset):]
|
||||
if limit:
|
||||
result = result[:long(limit)]
|
||||
|
||||
if count:
|
||||
return len(result)
|
||||
return result
|
||||
|
|
|
@ -200,6 +200,10 @@ class view_sc(osv.osv):
|
|||
'resource': lambda *a: 'ir.ui.menu',
|
||||
'user_id': lambda obj, cr, uid, context: uid,
|
||||
}
|
||||
_sql_constraints = [
|
||||
('shortcut_unique', 'unique(res_id, user_id)', 'Shortcut for this menu already exists!'),
|
||||
]
|
||||
|
||||
view_sc()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -146,11 +146,13 @@ class module(osv.osv):
|
|||
], string='State', readonly=True),
|
||||
'demo': fields.boolean('Demo data'),
|
||||
'license': fields.selection([
|
||||
('GPL-2', 'GPL-2'),
|
||||
('GPL-2', 'GPL Version 2'),
|
||||
('GPL-2 or any later version', 'GPL-2 or later version'),
|
||||
('GPL-3', 'GPL-3'),
|
||||
('GPL-3', 'GPL Version 3'),
|
||||
('GPL-3 or any later version', 'GPL-3 or later version'),
|
||||
('Other proprietary', 'Other proprietary')
|
||||
('AGPL-3', 'Affero GPL-3'),
|
||||
('Other OSI approved licence', 'Other OSI Approved Licence'),
|
||||
('Other proprietary', 'Other Proprietary')
|
||||
], string='License', readonly=True),
|
||||
'menus_by_module': fields.function(_get_views, method=True, string='Menus', type='text', multi="meta", store=True),
|
||||
'reports_by_module': fields.function(_get_views, method=True, string='Reports', type='text', multi="meta", store=True),
|
||||
|
@ -161,7 +163,7 @@ class module(osv.osv):
|
|||
_defaults = {
|
||||
'state': lambda *a: 'uninstalled',
|
||||
'demo': lambda *a: False,
|
||||
'license': lambda *a: 'GPL-2',
|
||||
'license': lambda *a: 'AGPL-3',
|
||||
}
|
||||
_order = 'name'
|
||||
|
||||
|
|
|
@ -275,6 +275,26 @@
|
|||
<field name="type">default</field>
|
||||
<field name="partner_id" ref="res_partner_agrolait"/>
|
||||
</record>
|
||||
<record id="res_partner_address_8delivery" model="res.partner.address">
|
||||
<field name="city">Wavre</field>
|
||||
<field name="name">Paul Lelitre</field>
|
||||
<field name="zip">5478</field>
|
||||
<field name="title">M.</field>
|
||||
<field model="res.country" name="country_id" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">71 rue de Chimay</field>
|
||||
<field name="type">delivery</field>
|
||||
<field name="partner_id" ref="res_partner_agrolait"/>
|
||||
</record>
|
||||
<record id="res_partner_address_8invoice" model="res.partner.address">
|
||||
<field name="city">Wavre</field>
|
||||
<field name="name">Serge Lelitre</field>
|
||||
<field name="zip">5478</field>
|
||||
<field name="title">M.</field>
|
||||
<field model="res.country" name="country_id" search="[('name','=','Belgium')]"/>
|
||||
<field name="street">69 rue de Chimay</field>
|
||||
<field name="type">invoice</field>
|
||||
<field name="partner_id" ref="res_partner_agrolait"/>
|
||||
</record>
|
||||
<record id="res_partner_address_9" model="res.partner.address">
|
||||
<field name="city">Paris</field>
|
||||
<field name="name">Arthur Grosbonnet</field>
|
||||
|
|
|
@ -60,11 +60,11 @@ class lang(osv.osv):
|
|||
('name_uniq', 'unique (name)', 'The name of the language must be unique !'),
|
||||
('code_uniq', 'unique (code)', 'The code of the language must be unique !'),
|
||||
]
|
||||
|
||||
|
||||
@tools.cache(skiparg=3)
|
||||
def _lang_data_get(self, cr, uid, lang_id, monetary=False):
|
||||
conv = localeconv()
|
||||
lang_obj=self.browse(cr,uid,lang_id)
|
||||
lang_obj = self.browse(cr, uid, lang_id)
|
||||
thousands_sep = lang_obj.thousands_sep or conv[monetary and 'mon_thousands_sep' or 'thousands_sep']
|
||||
decimal_point = lang_obj.decimal_point
|
||||
grouping = lang_obj.grouping
|
||||
|
@ -80,6 +80,7 @@ class lang(osv.osv):
|
|||
|
||||
if not grouping:
|
||||
return (s, 0)
|
||||
|
||||
result = ""
|
||||
seps = 0
|
||||
spaces = ""
|
||||
|
@ -129,7 +130,7 @@ class lang(osv.osv):
|
|||
parts = formatted.split('.')
|
||||
|
||||
if grouping:
|
||||
parts[0], seps = self._group(cr,uid,ids,parts[0], monetary=monetary, grouping=lang_grouping, thousands_sep=thousands_sep)
|
||||
parts[0], seps = self._group(cr,uid,ids,parts[0], monetary=monetary, grouping=lang_grouping, thousands_sep=thousands_sep)
|
||||
|
||||
formatted = decimal_point.join(parts)
|
||||
while seps:
|
||||
|
|
|
@ -6,9 +6,13 @@
|
|||
<field name="name">Partner Manager</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="menu_base_config">
|
||||
<field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
|
||||
</record>
|
||||
<record model="ir.ui.menu" id="menu_base_partner">
|
||||
<field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.menu" id="menu_base_config">
|
||||
<field eval="[(6,0,[ref('group_system'), ref('group_partner_manager')])]" name="groups_id"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -106,10 +106,11 @@ roles()
|
|||
|
||||
def _lang_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.lang')
|
||||
ids = obj.search(cr, uid, [])
|
||||
ids = obj.search(cr, uid, [('translatable','=',True)])
|
||||
res = obj.read(cr, uid, ids, ['code', 'name'], context)
|
||||
res = [(r['code'], r['name']) for r in res]
|
||||
return res
|
||||
|
||||
def _tz_get(self,cr,uid, context={}):
|
||||
return [(x, x) for x in pytz.all_timezones]
|
||||
|
||||
|
@ -245,6 +246,15 @@ class users(osv.osv):
|
|||
result = override_password(result)
|
||||
else:
|
||||
result = map(override_password, result)
|
||||
|
||||
if isinstance(result, list):
|
||||
for rec in result:
|
||||
if not rec.get('action_id',True):
|
||||
rec['action_id'] = (self._get_menu(cr, uid),'Menu')
|
||||
else:
|
||||
if not result.get('action_id',True):
|
||||
result['action_id'] = (self._get_menu(cr, uid),'Menu')
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
@ -467,6 +477,13 @@ class groups2(osv.osv): ##FIXME: Is there a reason to inherit this object ?
|
|||
_columns = {
|
||||
'users': fields.many2many('res.users', 'res_groups_users_rel', 'gid', 'uid', 'Users'),
|
||||
}
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for record in self.read(cr, uid, ids, ['users'], context=context):
|
||||
if record['users']:
|
||||
raise osv.except_osv(_('Warning !'), _('Make sure you have no users linked with the group(s)!'))
|
||||
return super(groups2, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
groups2()
|
||||
|
||||
class res_config_view(osv.osv_memory):
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
|
||||
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
|
||||
"access_ir_property_group_user","ir_property group_user","model_ir_property",,1,0,0,0
|
||||
"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,1
|
||||
"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,0
|
||||
"access_ir_report_custom_group_system","ir_report_custom group_system","model_ir_report_custom",,1,0,0,0
|
||||
"access_ir_report_custom_fields_group_system","ir_report_custom_fields group_system","model_ir_report_custom_fields",,1,0,0,0
|
||||
"access_ir_rule_group_user","ir_rule group_user","model_ir_rule",,1,0,0,0
|
||||
|
|
|
|
@ -47,11 +47,12 @@
|
|||
<rng:define name="assert">
|
||||
<rng:element name="assert">
|
||||
<rng:attribute name="model" />
|
||||
<rng:optional><rng:attribute name="search" /> </rng:optional>
|
||||
<rng:optional><rng:attribute name="search" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="count" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="string" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="id" /></rng:optional>
|
||||
<rng:optional><rng:attribute name="severity" /></rng:optional>
|
||||
<rng:oneOrMore>
|
||||
<rng:zeroOrMore>
|
||||
<rng:element name="test">
|
||||
<rng:attribute name="expr"/>
|
||||
<rng:choice>
|
||||
|
@ -59,7 +60,7 @@
|
|||
<rng:empty />
|
||||
</rng:choice>
|
||||
</rng:element>
|
||||
</rng:oneOrMore>
|
||||
</rng:zeroOrMore>
|
||||
</rng:element>
|
||||
</rng:define>
|
||||
|
||||
|
|
|
@ -382,7 +382,8 @@ class OpenERPDispatcherException(Exception):
|
|||
|
||||
class OpenERPDispatcher:
|
||||
def log(self, title, msg):
|
||||
Logger().notifyChannel('%s' % title, LOG_DEBUG_RPC, pformat(msg))
|
||||
if tools.config['log_level'] == logging.DEBUG_RPC:
|
||||
Logger().notifyChannel('%s' % title, LOG_DEBUG_RPC, pformat(msg))
|
||||
|
||||
def dispatch(self, service_name, method, params):
|
||||
try:
|
||||
|
|
|
@ -280,8 +280,11 @@ class expression(object):
|
|||
c = context.copy()
|
||||
c['active_test'] = False
|
||||
res_ids = field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c)
|
||||
right = map(lambda x: x[0], res_ids)
|
||||
self.__exp[i] = (left, 'in', right)
|
||||
if not res_ids:
|
||||
self.__exp[i] = ('id','=',0)
|
||||
else:
|
||||
right = map(lambda x: x[0], res_ids)
|
||||
self.__exp[i] = (left, 'in', right)
|
||||
else:
|
||||
# other field type
|
||||
# add the time part to datetime field when it's not there:
|
||||
|
|
|
@ -39,7 +39,7 @@ from psycopg2 import Binary
|
|||
import warnings
|
||||
|
||||
import tools
|
||||
|
||||
from tools.translate import _
|
||||
|
||||
def _symbol_set(symb):
|
||||
if symb == None or symb == False:
|
||||
|
@ -748,7 +748,7 @@ class related(function):
|
|||
ids=[ids]
|
||||
objlst = obj.browse(cr, uid, ids)
|
||||
for data in objlst:
|
||||
t_id=None
|
||||
t_id = None
|
||||
t_data = data
|
||||
relation = obj._name
|
||||
for i in range(len(self.arg)):
|
||||
|
|
166
bin/osv/orm.py
166
bin/osv/orm.py
|
@ -49,6 +49,7 @@ import string
|
|||
import sys
|
||||
import time
|
||||
import traceback
|
||||
import datetime
|
||||
import types
|
||||
|
||||
import fields
|
||||
|
@ -58,6 +59,7 @@ from tools.translate import _
|
|||
|
||||
import copy
|
||||
import sys
|
||||
import operator
|
||||
|
||||
try:
|
||||
from lxml import etree
|
||||
|
@ -86,7 +88,6 @@ def last_day_of_current_month():
|
|||
def intersect(la, lb):
|
||||
return filter(lambda x: x in lb, la)
|
||||
|
||||
|
||||
class except_orm(Exception):
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
|
@ -276,7 +277,7 @@ class browse_record(object):
|
|||
else:
|
||||
new_data[n] = data[n]
|
||||
self._data[data['id']].update(new_data)
|
||||
|
||||
|
||||
if not name in self._data[self._id]:
|
||||
#how did this happen?
|
||||
self.logger.notifyChannel("browse_record", netsvc.LOG_ERROR,
|
||||
|
@ -447,7 +448,7 @@ class orm_template(object):
|
|||
'name': k,
|
||||
'field_description': f.string.replace("'", " "),
|
||||
'ttype': f._type,
|
||||
'relation': f._obj or 'NULL',
|
||||
'relation': f._obj or '',
|
||||
'view_load': (f.view_load and 1) or 0,
|
||||
'select_level': tools.ustr(f.select or 0),
|
||||
'readonly':(f.readonly and 1) or 0,
|
||||
|
@ -544,6 +545,8 @@ class orm_template(object):
|
|||
return browse_null()
|
||||
|
||||
def __export_row(self, cr, uid, row, fields, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
def check_type(field_type):
|
||||
if field_type == 'float':
|
||||
|
@ -597,9 +600,9 @@ class orm_template(object):
|
|||
cols = selection_field(self._inherits)
|
||||
if cols and cols._type == 'selection':
|
||||
sel_list = cols.selection
|
||||
if type(sel_list) == type([]):
|
||||
r = [x[1] for x in sel_list if r==x[0]][0]
|
||||
|
||||
if r and type(sel_list) == type([]):
|
||||
r = [x[1] for x in sel_list if r==x[0]]
|
||||
r = r and r[0] or False
|
||||
if not r:
|
||||
if f[i] in self._columns:
|
||||
r = check_type(self._columns[f[i]]._type)
|
||||
|
@ -626,7 +629,7 @@ class orm_template(object):
|
|||
for rr in r :
|
||||
if isinstance(rr.name, browse_record):
|
||||
rr = rr.name
|
||||
rr_name = self.pool.get(rr._table_name).name_get(cr, uid, [rr.id])
|
||||
rr_name = self.pool.get(rr._table_name).name_get(cr, uid, [rr.id], context=context)
|
||||
rr_name = rr_name and rr_name[0] and rr_name[0][1] or ''
|
||||
dt += tools.ustr(rr_name or '') + ','
|
||||
data[fpos] = dt[:-1]
|
||||
|
@ -639,7 +642,7 @@ class orm_template(object):
|
|||
i += 1
|
||||
if i == len(f):
|
||||
if isinstance(r, browse_record):
|
||||
r = self.pool.get(r._table_name).name_get(cr, uid, [r.id])
|
||||
r = self.pool.get(r._table_name).name_get(cr, uid, [r.id], context=context)
|
||||
r = r and r[0] and r[0][1] or ''
|
||||
data[fpos] = tools.ustr(r or '')
|
||||
return [data] + lines
|
||||
|
@ -795,12 +798,12 @@ class orm_template(object):
|
|||
module, xml_id = line[i].rsplit('.', 1)
|
||||
else:
|
||||
module, xml_id = current_module, line[i]
|
||||
id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
|
||||
|
||||
res_res_id = ir_model_data_obj.read(cr, uid, [id],
|
||||
['res_id'])
|
||||
if res_res_id:
|
||||
res_id = res_res_id[0]['res_id']
|
||||
record_id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
|
||||
ir_model_data = ir_model_data_obj.read(cr, uid, [record_id], ['res_id'])
|
||||
if ir_model_data:
|
||||
res_id = ir_model_data[0]['res_id']
|
||||
else:
|
||||
raise ValueError('No references to %s.%s' % (module, xml_id))
|
||||
row[field[-1][:-3]] = res_id or False
|
||||
continue
|
||||
if (len(field) == len(prefix)+1) and \
|
||||
|
@ -994,7 +997,8 @@ class orm_template(object):
|
|||
msg = _('Insertion Failed! ' + e[1])
|
||||
return (-1, res, 'Line ' + str(counter) +' : ' + msg, '' )
|
||||
#Raising Uncaught exception
|
||||
raise
|
||||
return (-1, res, 'Line ' + str(counter) +' : ' + str(e), '' )
|
||||
|
||||
for lang in translate:
|
||||
context2 = context.copy()
|
||||
context2['lang'] = lang
|
||||
|
@ -1003,6 +1007,8 @@ class orm_template(object):
|
|||
data = pickle.load(file(config.get('import_partial')))
|
||||
data[filename] = initial_size - len(datas) + original_value
|
||||
pickle.dump(data, file(config.get('import_partial'),'wb'))
|
||||
if context.get('defer_parent_store_computation'):
|
||||
self._parent_store_compute(cr)
|
||||
cr.commit()
|
||||
|
||||
#except Exception, e:
|
||||
|
@ -1016,6 +1022,8 @@ class orm_template(object):
|
|||
#
|
||||
# TODO: Send a request with the result and multi-thread !
|
||||
#
|
||||
if context.get('defer_parent_store_computation'):
|
||||
self._parent_store_compute(cr)
|
||||
return (done, 0, 0, 0)
|
||||
|
||||
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
|
||||
|
@ -1108,8 +1116,7 @@ class orm_template(object):
|
|||
if getattr(self._columns[f], arg, None):
|
||||
res[f][arg] = getattr(self._columns[f], arg)
|
||||
|
||||
#TODO: optimize
|
||||
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US')
|
||||
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US', self._columns[f].string)
|
||||
if res_trans:
|
||||
res[f]['string'] = res_trans
|
||||
help_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'help', context.get('lang', False) or 'en_US')
|
||||
|
@ -1724,7 +1731,8 @@ class orm_template(object):
|
|||
for lang in langs:
|
||||
for field in vals:
|
||||
if field in self._columns:
|
||||
self.pool.get('ir.translation')._set_ids(cr, uid, self._name+','+field, 'field', lang, [0], vals[field])
|
||||
src = self._columns[field].string
|
||||
self.pool.get('ir.translation')._set_ids(cr, uid, self._name+','+field, 'field', lang, [0], vals[field], src)
|
||||
for table in self._inherits:
|
||||
cols = intersect(self._inherit_fields.keys(), vals)
|
||||
if cols:
|
||||
|
@ -2137,6 +2145,8 @@ class orm(orm_template):
|
|||
return (tables, where_clause)
|
||||
|
||||
def _parent_store_compute(self, cr):
|
||||
if not self._parent_store:
|
||||
return
|
||||
logger = netsvc.Logger()
|
||||
logger.notifyChannel('orm', netsvc.LOG_INFO, 'Computing parent left and right for table %s...' % (self._table, ))
|
||||
def browse_rec(root, pos=0):
|
||||
|
@ -2225,8 +2235,8 @@ class orm(orm_template):
|
|||
logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_left on object %s: fields.integer(\'Left Parent\', select=1)' % (self._table, ))
|
||||
if 'parent_right' not in self._columns:
|
||||
logger.notifyChannel('orm', netsvc.LOG_ERROR, 'create a column parent_right on object %s: fields.integer(\'Right Parent\', select=1)' % (self._table, ))
|
||||
if self._columns[self._parent_name].ondelete<>'cascade':
|
||||
logger.notifyChannel('orm', netsvc.LOG_ERROR, "the columns %s on object must be set as ondelete='cascasde'" % (self._name, self._parent_name))
|
||||
if self._columns[self._parent_name].ondelete != 'cascade':
|
||||
logger.notifyChannel('orm', netsvc.LOG_ERROR, "The column %s on object %s must be set as ondelete='cascade'" % (self._parent_name, self._name))
|
||||
cr.execute('ALTER TABLE "%s" ADD COLUMN "parent_left" INTEGER' % (self._table,))
|
||||
cr.execute('ALTER TABLE "%s" ADD COLUMN "parent_right" INTEGER' % (self._table,))
|
||||
cr.commit()
|
||||
|
@ -2472,6 +2482,8 @@ class orm(orm_template):
|
|||
cr.execute("SELECT relname FROM pg_class WHERE relkind in ('r','v') AND relname=%s", (self._table,))
|
||||
create = not bool(cr.fetchone())
|
||||
|
||||
cr.commit() # start a new transaction
|
||||
|
||||
for (key, con, _) in self._sql_constraints:
|
||||
conname = '%s_%s' % (self._table, key)
|
||||
cr.execute("SELECT conname FROM pg_constraint where conname=%s", (conname,))
|
||||
|
@ -2481,6 +2493,7 @@ class orm(orm_template):
|
|||
cr.commit()
|
||||
except:
|
||||
logger.notifyChannel('orm', netsvc.LOG_WARNING, 'unable to add \'%s\' constraint on table %s !\n If you want to have it, you should update the records and execute manually:\nALTER table %s ADD CONSTRAINT %s_%s %s' % (con, self._table, self._table, self._table, key, con,))
|
||||
cr.rollback()
|
||||
|
||||
if create:
|
||||
if hasattr(self, "_sql"):
|
||||
|
@ -2491,6 +2504,7 @@ class orm(orm_template):
|
|||
cr.commit()
|
||||
if store_compute:
|
||||
self._parent_store_compute(cr)
|
||||
cr.commit()
|
||||
return todo_end
|
||||
|
||||
def __init__(self, cr):
|
||||
|
@ -2646,11 +2660,16 @@ class orm(orm_template):
|
|||
for i in range(len(field_value)):
|
||||
field_value2.append({})
|
||||
for field2 in field_value[i]:
|
||||
if obj._columns[field2]._type in ('many2one', 'one2one'):
|
||||
if field2 in obj._columns.keys() and obj._columns[field2]._type in ('many2one', 'one2one'):
|
||||
obj2 = self.pool.get(obj._columns[field2]._obj)
|
||||
if not obj2.search(cr, uid,
|
||||
[('id', '=', field_value[i][field2])]):
|
||||
continue
|
||||
elif field2 in obj._inherit_fields.keys() and obj._inherit_fields[field2][2]._type in ('many2one', 'one2one'):
|
||||
obj2 = self.pool.get(obj._inherit_fields[field2][2]._obj)
|
||||
if not obj2.search(cr, uid,
|
||||
[('id', '=', field_value[i][field2])]):
|
||||
continue
|
||||
# TODO add test for many2many and one2many
|
||||
field_value2[i][field2] = field_value[i][field2]
|
||||
field_value = field_value2
|
||||
|
@ -3107,6 +3126,24 @@ class orm(orm_template):
|
|||
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'write', context=context)
|
||||
|
||||
# No direct update of parent_left/right
|
||||
vals.pop('parent_left', None)
|
||||
vals.pop('parent_right', None)
|
||||
|
||||
parents_changed = []
|
||||
if self._parent_store and (self._parent_name in vals):
|
||||
# The parent_left/right computation may take up to
|
||||
# 5 seconds. No need to recompute the values if the
|
||||
# parent is the same. Get the current value of the parent
|
||||
base_query = 'SELECT id FROM %s WHERE id IN %%s AND %s' % \
|
||||
(self._table, self._parent_name)
|
||||
params = (tuple(ids),)
|
||||
parent_val = vals[self._parent_name]
|
||||
if parent_val:
|
||||
cr.execute(base_query + " != %s", params + (parent_val,))
|
||||
else:
|
||||
cr.execute(base_query + " IS NULL", params)
|
||||
parents_changed = map(operator.itemgetter(0), cr.fetchall())
|
||||
|
||||
upd0 = []
|
||||
upd1 = []
|
||||
|
@ -3196,41 +3233,48 @@ class orm(orm_template):
|
|||
self.pool.get(table).write(cr, user, nids, v, context)
|
||||
|
||||
self._validate(cr, user, ids, context)
|
||||
# TODO: use _order to set dest at the right position and not first node of parent
|
||||
if self._parent_store and (self._parent_name in vals):
|
||||
|
||||
# TODO: use _order to set dest at the right position and not first node of parent
|
||||
# We can't defer parent_store computation because the stored function
|
||||
# fields that are computer may refer (directly or indirectly) to
|
||||
# parent_left/right (via a child_of domain)
|
||||
if parents_changed:
|
||||
if self.pool._init:
|
||||
self.pool._init_parent[self._name]=True
|
||||
else:
|
||||
for id in ids:
|
||||
# Find Position of the element
|
||||
if vals[self._parent_name]:
|
||||
cr.execute('select parent_left,parent_right,id from '+self._table+' where '+self._parent_name+'=%s order by '+(self._parent_order or self._order), (vals[self._parent_name],))
|
||||
else:
|
||||
cr.execute('select parent_left,parent_right,id from '+self._table+' where '+self._parent_name+' is null order by '+(self._parent_order or self._order))
|
||||
result_p = cr.fetchall()
|
||||
position = None
|
||||
for (pleft,pright,pid) in result_p:
|
||||
if pid == id:
|
||||
break
|
||||
position = pright+1
|
||||
order = self._parent_order or self._order
|
||||
parent_val = vals[self._parent_name]
|
||||
if parent_val:
|
||||
clause, params = '%s=%%s' % (self._parent_name,), (parent_val,)
|
||||
else:
|
||||
clause, params = '%s IS NULL' % (self._parent_name,), ()
|
||||
cr.execute('SELECT parent_right, id FROM %s WHERE %s ORDER BY %s' % (self._table, clause, order), params)
|
||||
parents = cr.fetchall()
|
||||
|
||||
# It's the first node of the parent: position = parent_left+1
|
||||
if not position:
|
||||
if not vals[self._parent_name]:
|
||||
position = 1
|
||||
else:
|
||||
cr.execute('select parent_left from '+self._table+' where id=%s', (vals[self._parent_name],))
|
||||
position = cr.fetchone()[0]+1
|
||||
|
||||
# We have the new position !
|
||||
cr.execute('select parent_left,parent_right from '+self._table+' where id=%s', (id,))
|
||||
pleft,pright = cr.fetchone()
|
||||
for id in parents_changed:
|
||||
cr.execute('SELECT parent_left, parent_right FROM %s WHERE id=%%s' % (self._table,), (id,))
|
||||
pleft, pright = cr.fetchone()
|
||||
distance = pright - pleft + 1
|
||||
|
||||
if position>pleft and position<=pright:
|
||||
# Find Position of the element
|
||||
position = None
|
||||
for (parent_pright, parent_id) in parents:
|
||||
if parent_id == id:
|
||||
break
|
||||
position = parent_pright+1
|
||||
|
||||
# It's the first node of the parent
|
||||
if not position:
|
||||
if not parent_val:
|
||||
position = 1
|
||||
else:
|
||||
cr.execute('select parent_left from '+self._table+' where id=%s', (parent_val,))
|
||||
position = cr.fetchone()[0]+1
|
||||
|
||||
if pleft < position <= pright:
|
||||
raise except_orm(_('UserError'), _('Recursivity Detected.'))
|
||||
|
||||
if pleft<position:
|
||||
if pleft < position:
|
||||
cr.execute('update '+self._table+' set parent_left=parent_left+%s where parent_left>=%s', (distance, position))
|
||||
cr.execute('update '+self._table+' set parent_right=parent_right+%s where parent_right>=%s', (distance, position))
|
||||
cr.execute('update '+self._table+' set parent_left=parent_left+%s, parent_right=parent_right+%s where parent_left>=%s and parent_left<%s', (position-pleft,position-pleft, pleft, pright))
|
||||
|
@ -3411,7 +3455,7 @@ class orm(orm_template):
|
|||
self.check_access_rule(cr, user, [id_new], 'create', context=context)
|
||||
upd_todo.sort(lambda x, y: self._columns[x].priority-self._columns[y].priority)
|
||||
|
||||
if self._parent_store:
|
||||
if self._parent_store and not context.get('defer_parent_store_computation'):
|
||||
if self.pool._init:
|
||||
self.pool._init_parent[self._name]=True
|
||||
else:
|
||||
|
@ -3639,8 +3683,9 @@ class orm(orm_template):
|
|||
* '&' (default), '|', '!'
|
||||
|
||||
"""
|
||||
if not context:
|
||||
if context is None:
|
||||
context = {}
|
||||
self.pool.get('ir.model.access').check(cr, user, self._name, 'read', context=context)
|
||||
# compute the where, order by, limit and offset clauses
|
||||
(qu1, qu2, tables) = self._where_calc(cr, user, args, context=context)
|
||||
dom = self.pool.get('ir.rule').domain_get(cr, user, self._name, 'read', context=context)
|
||||
|
@ -3750,9 +3795,9 @@ class orm(orm_template):
|
|||
:return: dictionary containing all the field values
|
||||
"""
|
||||
|
||||
if not context:
|
||||
if context is None:
|
||||
context = {}
|
||||
if not default:
|
||||
if default is None:
|
||||
default = {}
|
||||
if 'state' not in default:
|
||||
if 'state' in self._defaults:
|
||||
|
@ -3761,7 +3806,11 @@ class orm(orm_template):
|
|||
else:
|
||||
default['state'] = self._defaults['state']
|
||||
|
||||
data = self.read(cr, uid, [id], context=context)[0]
|
||||
context_wo_lang = context
|
||||
if 'lang' in context:
|
||||
del context_wo_lang['lang']
|
||||
data = self.read(cr, uid, [id], context=context_wo_lang)[0]
|
||||
|
||||
fields = self.fields_get(cr, uid, context=context)
|
||||
trans_data=[]
|
||||
for f in fields:
|
||||
|
@ -3796,17 +3845,14 @@ class orm(orm_template):
|
|||
|
||||
trans_obj = self.pool.get('ir.translation')
|
||||
#TODO: optimize translations
|
||||
trans_name=''
|
||||
for f in fields:
|
||||
trans_flag=True
|
||||
trans_name = ''
|
||||
if f in self._columns and self._columns[f].translate:
|
||||
trans_name=self._name+","+f
|
||||
trans_name = self._name+","+f
|
||||
elif f in self._inherit_fields and self._inherit_fields[f][2].translate:
|
||||
trans_name=self._inherit_fields[f][0]+","+f
|
||||
else:
|
||||
trans_flag=False
|
||||
trans_name = self._inherit_fields[f][0] + "," + f
|
||||
|
||||
if trans_flag:
|
||||
if trans_name:
|
||||
trans_ids = trans_obj.search(cr, uid, [
|
||||
('name', '=', trans_name),
|
||||
('res_id','=',data['id'])
|
||||
|
|
|
@ -253,7 +253,8 @@ class osv(osv_base, orm.orm):
|
|||
for c in cls.__dict__.get(s, []):
|
||||
exist = False
|
||||
for c2 in range(len(new)):
|
||||
if new[c2][2]==c[2]:
|
||||
#For _constraints, we should check field and methods as well
|
||||
if new[c2][2]==c[2] and new[c2][0]==c[0]:
|
||||
new[c2] = c
|
||||
exist = True
|
||||
break
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
##############################################################################
|
||||
|
||||
name = 'openerp-server'
|
||||
version = '5.2dev'
|
||||
major_version = '5.2'
|
||||
version = '6.0dev'
|
||||
major_version = '6.0'
|
||||
description = 'OpenERP Server'
|
||||
long_desc = '''\
|
||||
OpenERP is a complete ERP and CRM. The main features are accounting (analytic
|
||||
|
|
|
@ -36,6 +36,7 @@ from pychart import *
|
|||
import misc
|
||||
import cStringIO
|
||||
from lxml import etree
|
||||
from tools.translate import _
|
||||
|
||||
class external_pdf(render.render):
|
||||
def __init__(self, pdf):
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
|
@ -15,7 +15,7 @@
|
|||
# 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/>.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
@ -35,7 +35,7 @@ class report(object):
|
|||
for node in root_node:
|
||||
if node.tag == etree.Comment:
|
||||
continue
|
||||
if node.text:
|
||||
if node.text or node.tail:
|
||||
def _sub3(txt):
|
||||
n = node
|
||||
while n.tag != txt.group(2):
|
||||
|
@ -71,9 +71,9 @@ class report(object):
|
|||
n = n.getparent()
|
||||
n.set('rml_loop', txt.group(2))
|
||||
return '[['+txt.group(1)+"''"+txt.group(4)+']]'
|
||||
t = _regex1.sub(_sub1, node.text)
|
||||
t = _regex1.sub(_sub1, node.text or node.tail)
|
||||
if t == " ":
|
||||
t = _regex11.sub(_sub1, node.text)
|
||||
t = _regex11.sub(_sub1, node.text or node.tail)
|
||||
t = _regex3.sub(_sub3, t)
|
||||
node.text = _regex2.sub(_sub2, t)
|
||||
self.preprocess_rml(node,type)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
|
@ -15,7 +15,7 @@
|
|||
# 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/>.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
@ -52,13 +52,20 @@ class _rml_styles(object,):
|
|||
def __init__(self, nodes, localcontext):
|
||||
self.localcontext = localcontext
|
||||
self.styles = {}
|
||||
self.styles_obj = {}
|
||||
self.names = {}
|
||||
self.table_styles = {}
|
||||
self.default_style = reportlab.lib.styles.getSampleStyleSheet()
|
||||
|
||||
for node in nodes:
|
||||
for style in node.findall('blockTableStyle'):
|
||||
self.table_styles[style.get('id')] = self._table_style_get(style)
|
||||
for style in node.findall('paraStyle'):
|
||||
self.styles[style.get('name')] = self._para_style_update(style)
|
||||
sname = style.get('name')
|
||||
self.styles[sname] = self._para_style_update(style)
|
||||
|
||||
self.styles_obj[sname] = reportlab.lib.styles.ParagraphStyle(sname, self.default_style["Normal"], **self.styles[sname])
|
||||
|
||||
for variable in node.findall('initialize'):
|
||||
for name in variable.findall('name'):
|
||||
self.names[ name.get('id')] = name.get('value')
|
||||
|
@ -126,17 +133,19 @@ class _rml_styles(object,):
|
|||
|
||||
def para_style_get(self, node):
|
||||
style = False
|
||||
if node.get('style'):
|
||||
if node.get('style') in self.styles:
|
||||
styles = reportlab.lib.styles.getSampleStyleSheet()
|
||||
sname = node.get('style')
|
||||
style = reportlab.lib.styles.ParagraphStyle(sname, styles["Normal"], **self.styles[sname])
|
||||
sname = node.get('style')
|
||||
if sname:
|
||||
if sname in self.styles_obj:
|
||||
style = self.styles_obj[sname]
|
||||
else:
|
||||
sys.stderr.write('Warning: style not found, %s - setting default!\n' % (node.get('style'),) )
|
||||
if not style:
|
||||
styles = reportlab.lib.styles.getSampleStyleSheet()
|
||||
style = styles['Normal']
|
||||
style.__dict__.update(self._para_style_update(node))
|
||||
style = self.default_style['Normal']
|
||||
para_update = self._para_style_update(node)
|
||||
if para_update:
|
||||
# update style only is necessary
|
||||
style = copy.deepcopy(style)
|
||||
style.__dict__.update(para_update)
|
||||
return style
|
||||
|
||||
class _rml_doc(object):
|
||||
|
@ -167,7 +176,7 @@ class _rml_doc(object):
|
|||
from reportlab.lib.fonts import addMapping
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.pdfbase.ttfonts import TTFont
|
||||
|
||||
|
||||
pdfmetrics.registerFont(TTFont(fontname, filename ))
|
||||
if (mode == 'all'):
|
||||
addMapping(face, 0, 0, fontname) #normal
|
||||
|
@ -417,11 +426,11 @@ class _rml_canvas(object):
|
|||
self.canvas.drawPath(self.path, **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
|
||||
|
||||
def setFont(self, node):
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
from reportlab.pdfbase import pdfmetrics
|
||||
fname = node.get('name')
|
||||
#TODO : other fonts should be supported
|
||||
#TODO : other fonts should be supported
|
||||
if fname not in pdfmetrics.standardFonts:
|
||||
fname = self.canvas._fontname
|
||||
fname = self.canvas._fontname
|
||||
return self.canvas.setFont(fname, utils.unit_get(node.get('size')))
|
||||
|
||||
def render(self, node):
|
||||
|
@ -565,7 +574,7 @@ class _rml_flowable(object):
|
|||
def _illustration(self, node):
|
||||
class Illustration(platypus.flowables.Flowable):
|
||||
def __init__(self, node, localcontext, styles, self2):
|
||||
self.localcontext = localcontext
|
||||
self.localcontext = localcontext.copy()
|
||||
self.node = node
|
||||
self.styles = styles
|
||||
self.width = utils.unit_get(node.get('width'))
|
||||
|
|
|
@ -441,8 +441,8 @@ class report_sxw(report_rml, preprocess.report):
|
|||
rml_parser.set_context(objs, data, ids, report_xml.report_type)
|
||||
processed_rml = etree.XML(rml)
|
||||
if report_xml.header:
|
||||
rml_parser._add_header(processed_rml)
|
||||
processed_rml = self.preprocess_rml(processed_rml,report_xml.report_type)
|
||||
rml_parser._add_header(processed_rml, self.header)
|
||||
processed_rml = self.preprocess_rml(processed_rml,report_xml.report_type)
|
||||
if rml_parser.logo:
|
||||
logo = base64.decodestring(rml_parser.logo)
|
||||
create_doc = self.generators[report_xml.report_type]
|
||||
|
|
|
@ -283,8 +283,8 @@ class db(netsvc.ExportService):
|
|||
## Not True: in fact, check if connection to database is possible. The database may exists
|
||||
return bool(sql_db.db_connect(db_name))
|
||||
|
||||
def exp_list(self):
|
||||
if not tools.config['list_db']:
|
||||
def exp_list(self, document=False):
|
||||
if not tools.config['list_db'] and not document:
|
||||
raise Exception('AccessDenied')
|
||||
|
||||
db = sql_db.db_connect('template1')
|
||||
|
|
|
@ -123,7 +123,6 @@ class configmanager(object):
|
|||
parser.add_option("--assert-exit-level", dest='assert_exit_level', type="choice", choices=self._LOGLEVELS.keys(),
|
||||
help="specify the level at which a failed assertion will stop the server. Accepted values: %s" % (self._LOGLEVELS.keys(),))
|
||||
parser.add_option('--price_accuracy', dest='price_accuracy', default='2', help='deprecated since v6.0, replaced by module decimal_precision')
|
||||
parser.add_option('--no-database-list', action="store_false", dest='list_db', default=True, help="disable the ability to return the list of databases")
|
||||
|
||||
if self.has_ssl:
|
||||
group = optparse.OptionGroup(parser, "SSL Configuration")
|
||||
|
@ -136,7 +135,7 @@ class configmanager(object):
|
|||
default="server.pkey",
|
||||
help="specify the private key file for the SSL connection")
|
||||
parser.add_option_group(group)
|
||||
|
||||
|
||||
# Testing Group
|
||||
group = optparse.OptionGroup(parser, "Testing Configuration")
|
||||
group.add_option("--test-disable", action="store_true", dest="test_disable",
|
||||
|
@ -144,7 +143,7 @@ class configmanager(object):
|
|||
group.add_option("--test-commit", action="store_true", dest="test_commit",
|
||||
default=False, help="Commit database changes performed by tests.")
|
||||
parser.add_option_group(group)
|
||||
|
||||
|
||||
# Logging Group
|
||||
group = optparse.OptionGroup(parser, "Logging Configuration")
|
||||
group.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
|
||||
|
@ -161,8 +160,7 @@ class configmanager(object):
|
|||
group.add_option('--email-from', dest='email_from', default='', help='specify the SMTP email address for sending email')
|
||||
group.add_option('--smtp', dest='smtp_server', default='', help='specify the SMTP server for sending email')
|
||||
group.add_option('--smtp-port', dest='smtp_port', default='25', help='specify the SMTP port', type="int")
|
||||
if self.has_ssl:
|
||||
group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
|
||||
group.add_option('--smtp-ssl', dest='smtp_ssl', default='', help='specify the SMTP server support SSL or not')
|
||||
group.add_option('--smtp-user', dest='smtp_user', default='', help='specify the SMTP username for sending email')
|
||||
group.add_option('--smtp-password', dest='smtp_password', default='', help='specify the SMTP password for sending email')
|
||||
parser.add_option_group(group)
|
||||
|
@ -199,6 +197,13 @@ class configmanager(object):
|
|||
action="callback", callback=self._check_addons_path, nargs=1, type="string")
|
||||
parser.add_option_group(group)
|
||||
|
||||
security = optparse.OptionGroup(parser, 'Security-related options')
|
||||
security.add_option('--no-database-list', action="store_false", dest='list_db', default=True, help="disable the ability to return the list of databases")
|
||||
security.add_option('--enable-code-actions', action='store_true',
|
||||
dest='server_actions_allow_code', default=False,
|
||||
help='Enables server actions of state "code". Warning, this is a security risk.')
|
||||
parser.add_option_group(security)
|
||||
|
||||
def parse_config(self):
|
||||
(opt, args) = self.parser.parse_args()
|
||||
|
||||
|
@ -244,13 +249,13 @@ class configmanager(object):
|
|||
self.options['pidfile'] = False
|
||||
|
||||
keys = ['interface', 'port', 'db_name', 'db_user', 'db_password', 'db_host',
|
||||
'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout',
|
||||
'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout','smtp_ssl',
|
||||
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
|
||||
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
|
||||
'netrpc', 'xmlrpc', 'syslog', 'without_demo', 'timezone',]
|
||||
|
||||
if self.has_ssl:
|
||||
keys.extend(['smtp_ssl', 'secure_cert_file', 'secure_pkey_file'])
|
||||
keys.extend(['secure_cert_file', 'secure_pkey_file'])
|
||||
keys.append('secure')
|
||||
|
||||
for arg in keys:
|
||||
|
@ -258,7 +263,8 @@ class configmanager(object):
|
|||
self.options[arg] = getattr(opt, arg)
|
||||
|
||||
keys = ['language', 'translate_out', 'translate_in', 'debug_mode',
|
||||
'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog', 'list_db']
|
||||
'stop_after_init', 'logrotate', 'without_demo', 'netrpc', 'xmlrpc', 'syslog',
|
||||
'list_db', 'server_actions_allow_code']
|
||||
|
||||
if self.has_ssl and not self.options['secure']:
|
||||
keys.append('secure')
|
||||
|
|
|
@ -26,11 +26,9 @@ import os.path
|
|||
import pickle
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
|
||||
from datetime import datetime
|
||||
from lxml import etree
|
||||
|
||||
import ir
|
||||
import misc
|
||||
import netsvc
|
||||
|
@ -79,6 +77,7 @@ def _eval_xml(self,node, pool, cr, uid, idref, context=None):
|
|||
return f_val
|
||||
a_eval = node.get('eval','')
|
||||
if a_eval:
|
||||
import time
|
||||
idref2 = idref.copy()
|
||||
idref2['time'] = time
|
||||
idref2['DateTime'] = datetime
|
||||
|
@ -253,6 +252,14 @@ form: module.record_id""" % (xml_id,)
|
|||
self.pool.get(d_model).unlink(cr, self.uid, ids)
|
||||
self.pool.get('ir.model.data')._unlink(cr, self.uid, d_model, ids)
|
||||
|
||||
def _remove_ir_values(self, cr, name, value, model):
|
||||
ir_value_ids = self.pool.get('ir.values').search(cr, self.uid, [('name','=',name),('value','=',value),('model','=',model)])
|
||||
if ir_value_ids:
|
||||
self.pool.get('ir.values').unlink(cr, self.uid, ir_value_ids)
|
||||
self.pool.get('ir.model.data')._unlink(cr, self.uid, 'ir.values', ir_value_ids)
|
||||
|
||||
return True
|
||||
|
||||
def _tag_report(self, cr, rec, data_node=None):
|
||||
res = {}
|
||||
for dest,f in (('name','string'),('model','model'),('report_name','name')):
|
||||
|
@ -262,16 +269,17 @@ form: module.record_id""" % (xml_id,)
|
|||
if rec.get(field):
|
||||
res[dest] = rec.get(field).encode('utf8')
|
||||
if rec.get('auto'):
|
||||
res['auto'] = eval(rec.get('auto'))
|
||||
res['auto'] = eval(rec.get('auto','False'))
|
||||
if rec.get('sxw'):
|
||||
sxw_content = misc.file_open(rec.get('sxw')).read()
|
||||
res['report_sxw_content'] = sxw_content
|
||||
if rec.get('header'):
|
||||
res['header'] = eval(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'))
|
||||
res['multi'] = rec.get('multi') and eval(rec.get('multi','False'))
|
||||
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
|
||||
|
@ -291,12 +299,16 @@ form: module.record_id""" % (xml_id,)
|
|||
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)
|
||||
self.idref[xml_id] = int(id)
|
||||
|
||||
if not rec.get('menu') or eval(rec.get('menu','')):
|
||||
if not rec.get('menu') or eval(rec.get('menu','False')):
|
||||
keyword = str(rec.get('keyword', 'client_print_multi'))
|
||||
keys = [('action',keyword),('res_model',res['model'])]
|
||||
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)
|
||||
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)
|
||||
self._remove_ir_values(cr, res['name'], value, res['model'])
|
||||
return False
|
||||
|
||||
def _tag_function(self, cr, rec, data_node=None):
|
||||
|
@ -313,7 +325,7 @@ form: module.record_id""" % (xml_id,)
|
|||
name = rec.get("name",'').encode('utf8')
|
||||
xml_id = rec.get('id','').encode('utf8')
|
||||
self._test_xml_id(xml_id)
|
||||
multi = rec.get('multi','') and eval(rec.get('multi',''))
|
||||
multi = rec.get('multi','') and eval(rec.get('multi','False'))
|
||||
res = {'name': string, 'wiz_name': name, 'multi': multi, 'model': model}
|
||||
|
||||
if rec.get('groups'):
|
||||
|
@ -332,12 +344,16 @@ form: module.record_id""" % (xml_id,)
|
|||
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)
|
||||
self.idref[xml_id] = int(id)
|
||||
# ir_set
|
||||
if (not rec.get('menu') or eval(rec.get('menu',''))) and id:
|
||||
if (not rec.get('menu') or eval(rec.get('menu','False'))) and id:
|
||||
keyword = str(rec.get('keyword','') or 'client_action_multi')
|
||||
keys = [('action',keyword),('res_model',model)]
|
||||
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)
|
||||
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)
|
||||
self._remove_ir_values(cr, string, value, model)
|
||||
|
||||
def _tag_url(self, cr, rec, data_node=None):
|
||||
url = rec.get("string",'').encode('utf8')
|
||||
|
@ -351,12 +367,16 @@ form: module.record_id""" % (xml_id,)
|
|||
id = self.pool.get('ir.model.data')._update(cr, self.uid, "ir.actions.url", 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',''))) and id:
|
||||
if (not rec.get('menu') or eval(rec.get('menu','False'))) and id:
|
||||
keyword = str(rec.get('keyword','') or 'client_action_multi')
|
||||
keys = [('action',keyword)]
|
||||
value = 'ir.actions.url,'+str(id)
|
||||
replace = rec.get("replace",'') or True
|
||||
self.pool.get('ir.model.data').ir_set(cr, self.uid, 'action', keyword, url, ["ir.actions.url"], 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 URL having attribute menu=False on update
|
||||
value = 'ir.actions.url,'+str(id)
|
||||
self._remove_ir_values(cr, url, value, "ir.actions.url")
|
||||
|
||||
def _tag_act_window(self, cr, rec, data_node=None):
|
||||
name = rec.get('name','').encode('utf-8')
|
||||
|
@ -379,11 +399,12 @@ form: module.record_id""" % (xml_id,)
|
|||
uid = self.uid
|
||||
# def ref() added because , if context has ref('id') eval wil use this ref
|
||||
|
||||
active_id=str("active_id") # for further reference in client/bin/tools/__init__.py
|
||||
active_id = str("active_id") # for further reference in client/bin/tools/__init__.py
|
||||
|
||||
def ref(str_id):
|
||||
return self.id_get(cr, None, str_id)
|
||||
context = eval(context)
|
||||
# domain = eval(domain) # XXX need to test this line -> uid, active_id, active_ids, ...
|
||||
|
||||
res = {
|
||||
'name': name,
|
||||
|
|
|
@ -820,6 +820,22 @@ class cache(object):
|
|||
def to_xml(s):
|
||||
return s.replace('&','&').replace('<','<').replace('>','>')
|
||||
|
||||
def get_encodings():
|
||||
yield 'utf8'
|
||||
from locale import getpreferredencoding
|
||||
prefenc = getpreferredencoding()
|
||||
if prefenc:
|
||||
yield prefenc
|
||||
|
||||
prefenc = {
|
||||
'latin1': 'latin9',
|
||||
'iso-8859-1': 'iso8859-15',
|
||||
'cp1252': '1252',
|
||||
}.get(prefenc.lower())
|
||||
if prefenc:
|
||||
yield prefenc
|
||||
|
||||
|
||||
def ustr(value):
|
||||
"""This method is similar to the builtin `str` method, except
|
||||
it will return Unicode string.
|
||||
|
@ -829,29 +845,25 @@ def ustr(value):
|
|||
@rtype: unicode
|
||||
@return: unicode string
|
||||
"""
|
||||
orig = value
|
||||
if isinstance(value, Exception):
|
||||
return exception_to_unicode(value)
|
||||
|
||||
if isinstance(value, unicode):
|
||||
return value
|
||||
|
||||
if hasattr(value, '__unicode__'):
|
||||
try:
|
||||
return unicode(value)
|
||||
|
||||
if not isinstance(value, str):
|
||||
value = str(value)
|
||||
|
||||
try: # first try utf-8
|
||||
return unicode(value, 'utf-8')
|
||||
except:
|
||||
pass
|
||||
|
||||
try: # then extened iso-8858
|
||||
return unicode(value, 'iso-8859-15')
|
||||
except:
|
||||
pass
|
||||
for ln in get_encodings():
|
||||
try:
|
||||
return unicode(value, ln)
|
||||
except:
|
||||
pass
|
||||
raise UnicodeError('unable de to convert %r' % (orig,))
|
||||
|
||||
# else use default system locale
|
||||
from locale import getlocale
|
||||
return unicode(value, getlocale()[1])
|
||||
|
||||
def exception_to_unicode(e):
|
||||
if (sys.version_info[:2] < (2,6)) and hasattr(e, 'message'):
|
||||
|
@ -914,7 +926,7 @@ def get_languages():
|
|||
'fr_BE': u'French (BE) / Français (BE)',
|
||||
'fr_CH': u'French (CH) / Français (CH)',
|
||||
'fr_FR': u'French / Français',
|
||||
'gl_ES': u'Galician / Spain',
|
||||
'gl_ES': u'Galician / Galego',
|
||||
'gu_IN': u'Gujarati / India',
|
||||
'hi_IN': u'Hindi / India',
|
||||
'hr_HR': u'Croatian / hrvatski jezik',
|
||||
|
@ -939,8 +951,8 @@ def get_languages():
|
|||
'ro_RO': u'Romanian / limba română',
|
||||
'ru_RU': u'Russian / русский язык',
|
||||
'si_LK': u'Sinhalese / Sri Lanka',
|
||||
'sk_SK': u'Slovak / Slovakia',
|
||||
'sl_SL': u'Slovenian / slovenščina',
|
||||
'sl_SI': u'Slovenian / slovenščina',
|
||||
'sk_SK': u'Slovak / Slovenský jazyk',
|
||||
'sq_AL': u'Albanian / Shqipëri',
|
||||
'sr_RS': u'Serbian / Serbia',
|
||||
'sv_SE': u'Swedish / svenska',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
|
@ -15,7 +15,7 @@
|
|||
# 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/>.
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
|
@ -596,23 +596,30 @@ def trans_generate(lang, modules, dbname=None):
|
|||
push_translation(module, 'model', name, xml_name, encode(trad))
|
||||
|
||||
# parse source code for _() calls
|
||||
def get_module_from_path(path,mod_paths=None):
|
||||
if not mod_paths:
|
||||
# First, construct a list of possible paths
|
||||
def_path = os.path.abspath(os.path.join(tools.config['root_path'], 'addons')) # default addons path (base)
|
||||
ad_paths= map(lambda m: os.path.abspath(m.strip()),tools.config['addons_path'].split(','))
|
||||
mod_paths=[def_path]
|
||||
for adp in ad_paths:
|
||||
mod_paths.append(adp)
|
||||
if not adp.startswith('/'):
|
||||
mod_paths.append(os.path.join(def_path,adp))
|
||||
elif adp.startswith(def_path):
|
||||
mod_paths.append(adp[len(def_path)+1:])
|
||||
|
||||
for mp in mod_paths:
|
||||
if path.startswith(mp) and (os.path.dirname(path) != mp):
|
||||
path = path[len(mp)+1:]
|
||||
return path.split(os.path.sep)[0]
|
||||
def get_module_from_path(path, mod_paths=None):
|
||||
# if not mod_paths:
|
||||
## First, construct a list of possible paths
|
||||
# def_path = os.path.abspath(os.path.join(tools.config['root_path'], 'addons')) # default addons path (base)
|
||||
# ad_paths= map(lambda m: os.path.abspath(m.strip()),tools.config['addons_path'].split(','))
|
||||
# mod_paths=[def_path]
|
||||
# for adp in ad_paths:
|
||||
# mod_paths.append(adp)
|
||||
# if not adp.startswith('/'):
|
||||
# mod_paths.append(os.path.join(def_path,adp))
|
||||
# elif adp.startswith(def_path):
|
||||
# mod_paths.append(adp[len(def_path)+1:])
|
||||
# for mp in mod_paths:
|
||||
# if path.startswith(mp) and (os.path.dirname(path) != mp):
|
||||
# path = path[len(mp)+1:]
|
||||
# return path.split(os.path.sep)[0]
|
||||
path_dir = os.path.dirname(path[1:])
|
||||
if path_dir:
|
||||
if os.path.exists(os.path.join(tools.config['addons_path'],path[1:])):
|
||||
return path.split(os.path.sep)[1]
|
||||
else:
|
||||
root_addons = os.path.join(tools.config['root_path'], 'addons')
|
||||
if os.path.exists(os.path.join(root_addons,path[1:])):
|
||||
return path.split(os.path.sep)[1]
|
||||
return 'base' # files that are not in a module are considered as being in 'base' module
|
||||
|
||||
modobj = pool.get('ir.module.module')
|
||||
|
@ -699,6 +706,11 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
if not lang_name:
|
||||
lang_name = tools.get_languages().get(lang, lang)
|
||||
|
||||
def fix_xa0(s):
|
||||
if s == '\xa0':
|
||||
return '\xc2\xa0'
|
||||
return s
|
||||
|
||||
lang_info = {
|
||||
'code': lang,
|
||||
'iso_code': iso_lang,
|
||||
|
@ -706,9 +718,10 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
'translatable': 1,
|
||||
'date_format' : str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y')),
|
||||
'time_format' : str(locale.nl_langinfo(locale.T_FMT)),
|
||||
'decimal_point' : str(locale.localeconv()['decimal_point']).replace('\xa0', '\xc2\xa0'),
|
||||
'thousands_sep' : str(locale.localeconv()['thousands_sep']).replace('\xa0', '\xc2\xa0'),
|
||||
'decimal_point' : fix_xa0(str(locale.localeconv()['decimal_point'])),
|
||||
'thousands_sep' : fix_xa0(str(locale.localeconv()['thousands_sep'])),
|
||||
}
|
||||
|
||||
try:
|
||||
lang_obj.create(cr, uid, lang_info)
|
||||
finally:
|
||||
|
@ -767,7 +780,7 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
|
|||
# the same source
|
||||
obj = pool.get(model)
|
||||
if obj:
|
||||
if not field in obj._columns:
|
||||
if field not in obj.fields_get_keys(cr, uid):
|
||||
continue
|
||||
ids = obj.search(cr, uid, [(field, '=', dic['src'])])
|
||||
|
||||
|
|
1108
doc/Changelog
1108
doc/Changelog
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@ formats=rpm
|
|||
|
||||
[bdist_rpm]
|
||||
# release must exactly match 'release' as set in bin/release.py
|
||||
release=3
|
||||
release=10
|
||||
|
||||
requires=python >= 2.4
|
||||
#build-requires=python-devel >= 2.3
|
||||
|
|
15
setup.py
15
setup.py
|
@ -44,7 +44,7 @@ sys.path.append(join(os.path.abspath(os.path.dirname(__file__)), "bin"))
|
|||
|
||||
execfile(join('bin', 'release.py'))
|
||||
|
||||
if sys.argv[1] == 'bdist_rpm':
|
||||
if 'bdist_rpm' in sys.argv:
|
||||
version = version.split('-')[0]
|
||||
|
||||
# get python short version
|
||||
|
@ -177,11 +177,14 @@ options = {
|
|||
"compressed": 1,
|
||||
"optimize": 2,
|
||||
"dist_dir": 'dist',
|
||||
"packages": ["lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
|
||||
"lxml.objectify", "decimal", "xml", "encodings",
|
||||
"dateutil", "wizard", "pychart", "PIL", "pyparsing",
|
||||
"pydot", "asyncore","asynchat", "reportlab", "vobject",
|
||||
"HTMLParser", "select", "yaml", "pywebdav"],
|
||||
"packages": [
|
||||
"lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
|
||||
"lxml.objectify", "decimal", "xml", "xml", "xml.dom", "xml.xpath",
|
||||
"encodings", "dateutil", "wizard", "pychart", "PIL", "pyparsing",
|
||||
"pydot", "asyncore","asynchat", "reportlab", "vobject",
|
||||
"HTMLParser", "select", "mako", "poplib",
|
||||
"imaplib", "smtplib", "email", "yaml","pywebdav",
|
||||
],
|
||||
"excludes" : ["Tkconstants","Tkinter","tcl"],
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue