Merge commit 'origin/master' into xrg

Conflicts:
	bin/netsvc.py
	bin/report/report_sxw.py
	setup.py

bzr revid: p_christ@hol.gr-20090803072357-zz2cm1sycsagftnn
This commit is contained in:
P. Christeas 2009-08-03 10:23:57 +03:00
commit c3e569fb08
20 changed files with 356 additions and 132 deletions

View File

@ -675,6 +675,17 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
status = {}
cr = db.cursor()
if cr:
cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname='ir_module_module'")
if len(cr.fetchall())==0:
logger.notifyChannel("init", netsvc.LOG_INFO, "init db")
tools.init_db(cr)
# cr.execute("update res_users set password=%s where id=%s",('admin',1))
# in that case, force --init=all
tools.config["init"]["all"] = 1
tools.config['update']['all'] = 1
if not tools.config['without_demo']:
tools.config["demo"]['all'] = 1
force = []
if force_demo:
force.append('demo')

View File

@ -7,13 +7,13 @@ msgstr ""
"Project-Id-Version: OpenERP Server 5.0.0\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2009-05-19 14:36+0000\n"
"PO-Revision-Date: 2009-06-08 09:44+0000\n"
"Last-Translator: Olivier (OpenERP) <Unknown>\n"
"PO-Revision-Date: 2009-07-07 13:42+0000\n"
"Last-Translator: Olivier (Open ERP) <Unknown>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2009-06-08 09:48+0000\n"
"X-Launchpad-Export-Date: 2009-07-07 14:08+0000\n"
"X-Generator: Launchpad (build Unknown)\n"
#. module: base
@ -3424,7 +3424,6 @@ msgstr "Configuration de l'action client"
#. module: base
#: model:ir.actions.act_window,name:base.action_partner_address_form
#: model:ir.model,name:base.model_res_partner_address
#: model:ir.ui.menu,name:base.menu_partner_address_form
#: view:res.partner.address:0
msgid "Partner Addresses"
msgstr "Adresses des Partenaires"
@ -4024,7 +4023,7 @@ msgstr "Etat d'Esprit Partenaire"
#. module: base
#: selection:ir.ui.view,type:0
msgid "mdx"
msgstr ""
msgstr "mdx"
#. module: base
#: model:res.country,name:base.bi
@ -6348,7 +6347,7 @@ msgstr "Voir la Réf."
#. module: base
#: selection:module.lang.install,init,lang:0
msgid "Dutch (Belgium) / Nederlands (Belgïe)"
msgstr ""
msgstr "Néerlandais (Belgique) / Nederlands (Belgïe)"
#. module: base
#: model:ir.actions.act_window,name:base.open_repository_tree

View File

@ -73,7 +73,7 @@ class ir_model(osv.osv):
def write(self, cr, user, ids, vals, context=None):
if context:
del context['__last_update']
context.pop('__last_update', None)
return super(ir_model,self).write(cr, user, ids, vals, context)
def create(self, cr, user, vals, context=None):
@ -229,6 +229,9 @@ class ir_model_fields(osv.osv):
'field_description': lambda *a: '',
}
_order = "id"
_sql_constraints = [
('size_gt_zero', 'CHECK (size>0)', 'Size of the field can never be less than 1 !'),
]
def unlink(self, cr, user, ids, context=None):
for field in self.browse(cr, user, ids, context):
if field.state <> 'manual':
@ -244,17 +247,18 @@ class ir_model_fields(osv.osv):
vals['model'] = model_data.model
if context and context.get('manual',False):
vals['state'] = 'manual'
res = super(ir_model_fields,self).create(cr, user, vals, context)
res = super(ir_model_fields,self).create(cr, user, vals, context)
if vals.get('state','base') == 'manual':
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'])]):
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.get(vals['model'])._auto_init(cr, {})
return res
ir_model_fields()

View File

@ -35,7 +35,7 @@ def _check_xml(self, cr, uid, ids, context={}):
if not relaxng.validate(eview):
logger = netsvc.Logger()
logger.notifyChannel('init', netsvc.LOG_ERROR, 'The view does not fit the required schema !')
logger.notifyChannel('init', netsvc.LOG_ERROR, relaxng.error_log.last_error)
logger.notifyChannel('init', netsvc.LOG_ERROR, tools.ustr(relaxng.error_log.last_error))
return False
return True

View File

@ -480,7 +480,7 @@ class module(osv.osv):
if not mod.description:
logger.notifyChannel("init", netsvc.LOG_WARNING, 'module %s: description is empty !' % (mod.name,))
if not mod.certificate:
if not mod.certificate or not mod.certificate.isdigit():
logger.notifyChannel('init', netsvc.LOG_WARNING, 'module %s: no quality certificate' % (mod.name,))
else:
val = long(mod.certificate[2:]) % 97 == 29

View File

@ -7,8 +7,10 @@
<xsl:variable name="rightMargin">1cm</xsl:variable>
<xsl:variable name="topMargin">1cm</xsl:variable>
<xsl:variable name="bottomMargin">1cm</xsl:variable>
<xsl:variable name="pageSize">29.7cm,21cm</xsl:variable>
<!--:variable name="pageSize">29.7cm,21cm</xsl:variable> Or use default width and height for frame -->
<xsl:variable name="pageSize">
<xsl:value-of select="/report/config/PageSize"/>
</xsl:variable>
<xsl:variable name="page_format">a4_letter</xsl:variable>
<xsl:template name="first_page_frames">

View File

@ -24,7 +24,6 @@
#
##############################################################################
import SimpleXMLRPCServer
import SocketServer
import logging
@ -121,7 +120,7 @@ def init_logger():
handler = logging.handlers.FileHandler(logf)
except Exception, ex:
sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n")
handler = logging.StreamHandler(sys.stdout)
handler = logging.StreamHandler(sys.stdout)
else:
# Normal Handler on standard output
handler = logging.StreamHandler(sys.stdout)
@ -158,7 +157,10 @@ def init_logger():
class Logger(object):
def notifyChannel(self, name, level, msg):
from service.web_services import common
log = logging.getLogger(tools.ustr(name))
if level == LOG_DEBUG_RPC and not hasattr(log, level):
@ -171,6 +173,9 @@ class Logger(object):
msg = tools.exception_to_unicode(msg)
try:
if level in (LOG_ERROR,LOG_CRITICAL):
msg = common().get_server_environment() + msg
result = tools.ustr(msg).strip().split('\n')
except UnicodeDecodeError:
result = msg.strip().split('\n')
@ -210,7 +215,7 @@ class Agent(object):
for timer in self._timers[db]:
if not timer.isAlive():
self._timers[db].remove(timer)
@classmethod
def cancel(cls, db_name):
"""Cancel all timers for a given database. If None passed, all timers are cancelled"""
@ -218,7 +223,7 @@ class Agent(object):
if db_name is None or db == db_name:
for timer in cls._timers[db]:
timer.cancel()
@classmethod
def quit(cls):
cls.cancel(None)

View File

@ -198,10 +198,22 @@ class expression(object):
self.__exp[i] = (left, 'in', right)
else:
# other field type
# add the time part to datetime field when it's not there:
if field._type == 'datetime' and self.__exp[i][2] and len(self.__exp[i][2]) == 10:
self.__exp[i] = list(self.__exp[i])
if operator in ('>', '>='):
self.__exp[i][2] += ' 00:00:00'
elif operator in ('<', '<='):
self.__exp[i][2] += ' 23:59:59'
self.__exp[i] = tuple(self.__exp[i])
if field.translate:
if operator in ('like', 'ilike', 'not like', 'not ilike'):
right = '%%%s%%' % right
operator = operator == '=like' and 'like' or operator
query1 = '( SELECT res_id' \
@ -224,7 +236,7 @@ class expression(object):
' SELECT id' \
' FROM "' + working_table._table + '"' \
' WHERE "' + left + '" ' + operator + instr + ")"
query2 = [working_table._name + ',' + left,
context.get('lang', False) or 'en_US',
'model',

View File

@ -390,8 +390,12 @@ class orm_template(object):
vals['select_level']
))
if 'module' in context:
name1 = 'field_' + self._table + '_' + k
cr.execute("select name from ir_model_data where name='%s'"%(name1))
if cr.fetchone():
name1 = name1 + "_" + str(id)
cr.execute("INSERT INTO ir_model_data (name,date_init,date_update,module,model,res_id) VALUES (%s, now(), now(), %s, %s, %s)", \
(('field_'+self._table+'_'+k)[:64], context['module'], 'ir.model.fields', id)
(name1[:64], context['module'], 'ir.model.fields', id)
)
else:
for key, val in vals.items():
@ -443,32 +447,45 @@ class orm_template(object):
def __export_row(self, cr, uid, row, fields, context=None):
def check_type(type,r):
if type == 'float':
def check_type(field_type):
if field_type == 'float':
return 0.0
elif type == 'integer':
elif field_type == 'integer':
return 0
elif type == 'char':
return ''
return r
elif field_type == 'boolean':
return False
return ''
lines = []
data = map(lambda x: '', range(len(fields)))
done = []
for fpos in range(len(fields)):
f = fields[fpos]
f = fields[fpos]
if f:
r = row
i = 0
while i < len(f):
r = r[f[i]]
if f[i] == 'db_id':
r = r['id']
elif f[i] == 'id':
model_data = self.pool.get('ir.model.data')
data_ids = model_data.search(cr, uid, [('model','=',r._table_name),('res_id','=',r['id'])])
if len(data_ids):
d = model_data.read(cr, uid, data_ids, ['name','module'])[0]
if d['module']:
r = '%s.%s'%(d['module'],d['name'])
else:
r = d['name']
else:
break
else:
r = r[f[i]]
if not r:
if f[i] in self._columns:
r = check_type(self._columns[f[i]]._type,r)
r = check_type(self._columns[f[i]]._type)
elif f[i] in self._inherit_fields:
r = check_type(self._inherit_fields[f[i]][2]._type,r)
data[fpos] = tools.ustr(r)
r = check_type(self._inherit_fields[f[i]][2]._type)
data[fpos] = r
break
if isinstance(r, (browse_record_list, list)):
first = True
@ -476,56 +493,89 @@ class orm_template(object):
or [], fields)
if fields2 in done:
break
done.append(fields2)
done.append(fields2)
for row2 in r:
lines2 = self.__export_row(cr, uid, row2, fields2,
context)
context)
if first:
for fpos2 in range(len(fields)):
if lines2 and lines2[0][fpos2]:
data[fpos2] = lines2[0][fpos2]
if not data[fpos]:
dt = ''
for rr in r :
if isinstance(rr.name, browse_record):
rr = rr.name
dt+=rr.name+','
data[fpos] = dt[:-1]
break
lines += lines2[1:]
first = False
else:
lines += lines2
lines += lines2
break
i += 1
if i == len(f):
if isinstance(r, browse_record):
r = r.name
data[fpos] = tools.ustr(r or '')
return [data] + lines
def export_data(self, cr, uid, ids, fields, context=None):
def export_data(self, cr, uid, ids, fields_to_export, context=None):
if not context:
context = {}
fields = map(lambda x: x.split('/'), fields)
imp_comp = context.get('import_comp',False)
cols = self._columns.copy()
for f in self._inherit_fields:
cols.update({f: self._inherit_fields[f][2]})
fields_to_export = map(lambda x: x.split('/'), fields_to_export)
fields_export = fields_to_export+[]
warning = ''
warning_fields = []
for field in fields_export:
if imp_comp and len(field)>1:
warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field)))
elif len (field) <=1:
if imp_comp and cols.get(field and field[0],False):
if ((isinstance(cols[field[0]], fields.function) and not cols[field[0]].store) \
or isinstance(cols[field[0]], fields.related)\
or isinstance(cols[field[0]], fields.one2many)):
warning_fields.append('/'.join(map(lambda x:x in cols and cols[x].string or x,field)))
datas = []
if imp_comp and len(warning_fields):
warning = 'Following columns cannot be exported since you select to be import compatible.\n%s' %('\n'.join(warning_fields))
cr.rollback()
return {'warning' : warning}
for row in self.browse(cr, uid, ids, context):
datas += self.__export_row(cr, uid, row, fields, context)
return datas
datas += self.__export_row(cr, uid, row, fields_to_export, context)
return {'datas':datas}
def import_data(self, cr, uid, fields, datas, mode='init', current_module='', noupdate=False, context=None, filename=None):
if not context:
context = {}
fields = map(lambda x: x.split('/'), fields)
logger = netsvc.Logger()
def process_liness(self, datas, prefix, fields_def, position=0):
ir_model_data_obj = self.pool.get('ir.model.data')
def process_liness(self, datas, prefix, current_module, model_name, fields_def, position=0):
line = datas[position]
row = {}
translate = {}
todo = []
warning = ''
data_id = False
data_res_id = False
is_xml_id = False
is_db_id = False
ir_model_data_obj = self.pool.get('ir.model.data')
#
# Import normal fields
#
for i in range(len(fields)):
if i >= len(line):
raise Exception(_('Please check that all your lines have %d columns.') % (len(fields),))
field = fields[i]
if field == ["id"]:
data_id = line[i]
if not line[i]:
continue
field = fields[i]
if (len(field)==len(prefix)+1) and field[len(prefix)].endswith(':id'):
res_id = False
if line[i]:
@ -535,8 +585,7 @@ class orm_template(object):
if '.' in word:
module, xml_id = word.rsplit('.', 1)
else:
module, xml_id = current_module, word
ir_model_data_obj = self.pool.get('ir.model.data')
module, xml_id = current_module, word
id = ir_model_data_obj._get_id(cr, uid, module,
xml_id)
res_id2 = ir_model_data_obj.read(cr, uid, [id],
@ -549,8 +598,7 @@ class orm_template(object):
if '.' in line[i]:
module, xml_id = line[i].rsplit('.', 1)
else:
module, xml_id = current_module, line[i]
ir_model_data_obj = self.pool.get('ir.model.data')
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'])
@ -565,6 +613,63 @@ class orm_template(object):
continue
if (len(field) == len(prefix)+1) and \
(prefix == field[0:len(prefix)]):
if field[len(prefix)] == "id":
# XML ID
db_id = False
is_xml_id = data_id = line[i]
d = data_id.split('.')
module = len(d)>1 and d[0] or ''
name = len(d)>1 and d[1] or d[0]
data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('name','=',name)])
if len(data_ids):
d = ir_model_data_obj.read(cr, uid, data_ids, ['res_id'])[0]
db_id = d['res_id']
if is_db_id and not db_id:
data_ids = ir_model_data_obj.search(cr, uid, [('module','=',module),('model','=',model_name),('res_id','=',is_db_id)])
if not len(data_ids):
ir_model_data_obj.create(cr, uid, {'module':module, 'model':model_name, 'name':name, 'res_id':is_db_id})
db_id = is_db_id
if is_db_id and int(db_id) != int(is_db_id):
warning += ("Id is not the same than existing one: " + str(is_db_id) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Id is not the same than existing one: " + str(is_db_id) + ' !\n')
continue
if field[len(prefix)] == "db_id":
# Database ID
try:
line[i]= int(line[i])
except Exception, e:
warning += (str(e) + "!\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
str(e) + '!\n')
continue
is_db_id = line[i]
obj_model = self.pool.get(model_name)
ids = obj_model.search(cr, uid, [('id','=',line[i])])
if not len(ids):
warning += ("Database ID doesn't exist: " + model_name + ": " + str(line[i]) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Database ID doesn't exist: " + model_name + ": " + str(line[i]) + ' !\n')
continue
else:
data_res_id = ids[0]
data_ids = ir_model_data_obj.search(cr, uid, [('model','=',model_name),('res_id','=',line[i])])
if len(data_ids):
d = ir_model_data_obj.read(cr, uid, data_ids, ['name','module'])[0]
data_id = d['name']
if d['module']:
data_id = '%s.%s'%(d['module'],d['name'])
else:
data_id = d['name']
if is_xml_id and not data_id:
data_id = is_xml_id
if is_xml_id and is_xml_id!=data_id:
warning += ("Id is not the same than existing one: " + str(line[i]) + " !\n")
logger.notifyChannel("import", netsvc.LOG_ERROR,
"Id is not the same than existing one: " + str(line[i]) + ' !\n')
continue
if fields_def[field[len(prefix)]]['type'] == 'integer':
res = line[i] and int(line[i])
elif fields_def[field[len(prefix)]]['type'] == 'boolean':
@ -580,18 +685,22 @@ class orm_template(object):
sel = fields_def[field[len(prefix)]]['selection'](self,
cr, uid, context)
for key, val in sel:
if str(key) == line[i]:
if line[i] in [tools.ustr(key),tools.ustr(val)]: #Acepting key or value for selection field
res = key
break
if line[i] and not res:
logger.notifyChannel("import", netsvc.LOG_WARNING,
"key '%s' not found in selection field '%s'" % \
(line[i], field[len(prefix)]))
warning += "Key/value '"+ str(line[i]) +"' not found in selection field '"+str(field[len(prefix)])+"'"
elif fields_def[field[len(prefix)]]['type']=='many2one':
res = False
if line[i]:
relation = fields_def[field[len(prefix)]]['relation']
res2 = self.pool.get(relation).name_search(cr, uid,
line[i], [], operator='=')
line[i], [], operator='=', context=context)
res = (res2 and res2[0][0]) or False
if not res:
warning += ('Relation not found: ' + line[i] + \
@ -605,7 +714,7 @@ class orm_template(object):
relation = fields_def[field[len(prefix)]]['relation']
for word in line[i].split(config.get('csv_internal_sep')):
res2 = self.pool.get(relation).name_search(cr,
uid, word, [], operator='=')
uid, word, [], operator='=', context=context)
res3 = (res2 and res2[0][0]) or False
if not res3:
warning += ('Relation not found: ' + \
@ -625,19 +734,20 @@ class orm_template(object):
if field[0] not in todo:
todo.append(field[len(prefix)])
#
# Import one2many fields
# Import one2many, many2many fields
#
nbrmax = 1
for field in todo:
newfd = self.pool.get(fields_def[field]['relation']).fields_get(
relation_obj = self.pool.get(fields_def[field]['relation'])
newfd = relation_obj.fields_get(
cr, uid, context=context)
res = process_liness(self, datas, prefix + [field], newfd, position)
(newrow, max2, w2, translate2, data_id2) = res
res = process_liness(self, datas, prefix + [field], current_module, relation_obj._name, newfd, position)
(newrow, max2, w2, translate2, data_id2, data_res_id2) = res
nbrmax = max(nbrmax, max2)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
warning = warning + w2
reduce(lambda x, y: x and y, newrow)
row[field] = (reduce(lambda x, y: x or y, newrow.values()) and \
[(0, 0, newrow)]) or []
[(0, 0, newrow)]) or []
i = max2
while (position+i)<len(datas):
ok = True
@ -648,11 +758,11 @@ class orm_template(object):
if not ok:
break
(newrow, max2, w2, translate2, data_id2) = process_liness(
self, datas, prefix+[field], newfd, position+i)
(newrow, max2, w2, translate2, data_id2, data_res_id2) = process_liness(
self, datas, prefix+[field], current_module, relation_obj._name, newfd, position+i)
warning = warning+w2
if reduce(lambda x, y: x or y, newrow.values()):
row[field].append((0, 0, newrow))
row[field].append((0, 0, newrow))
i += max2
nbrmax = max(nbrmax, i)
@ -660,7 +770,7 @@ class orm_template(object):
for i in range(max(nbrmax, 1)):
#if datas:
datas.pop(0)
result = (row, nbrmax, warning, translate, data_id)
result = (row, nbrmax, warning, translate, data_id, data_res_id)
return result
fields_def = self.fields_get(cr, uid, context=context)
@ -675,16 +785,16 @@ class orm_template(object):
counter += 1
res = {}
#try:
(res, other, warning, translate, data_id) = \
process_liness(self, datas, [], fields_def)
if warning:
(res, other, warning, translate, data_id, res_id) = \
process_liness(self, datas, [], current_module, self._name, fields_def)
if warning:
cr.rollback()
return (-1, res, warning, '')
return (-1, res, 'Line ' + str(counter) +' : ' + warning, '')
try:
id = self.pool.get('ir.model.data')._update(cr, uid, self._name,
id = ir_model_data_obj._update(cr, uid, self._name,
current_module, res, xml_id=data_id, mode=mode,
noupdate=noupdate)
noupdate=noupdate, res_id=res_id)
except Exception, e:
import psycopg2
if isinstance(e,psycopg2.IntegrityError):
@ -693,7 +803,7 @@ class orm_template(object):
if key in e[0]:
msg = self.pool._sql_error[key]
break
return (-1, res,msg,'' )
return (-1, res,'Line ' + str(counter) +' : ' + msg,'' )
for lang in translate:
context2 = context.copy()

View File

@ -27,8 +27,10 @@ from lxml import etree
from report import render
import libxml2
import libxslt
import locale
import time, os
import mx.DateTime
class report_printscreen_list(report_int):
def __init__(self, name):
@ -87,7 +89,8 @@ class report_printscreen_list(report_int):
n.text = text
config.append(n)
_append_node('date', time.strftime('%d/%m/%Y'))
#_append_node('date', time.strftime('%d/%m/%Y'))
_append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
_append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
@ -106,7 +109,7 @@ class report_printscreen_list(report_int):
for f in fields_order:
s = 0
ince += 1
if fields[f]['type'] in ('date','time','float','integer'):
if fields[f]['type'] in ('date','time','datetime','float','integer'):
s = 60
strmax -= s
if fields[f]['type'] in ('float','integer'):
@ -132,13 +135,11 @@ class report_printscreen_list(report_int):
new_doc.append(header)
lines = etree.Element("lines")
tsum = []
count = len(fields_order)
for i in range(0,count):
tsum.append(0)
for line in results:
node_line = etree.Element("row")
count = -1
@ -158,10 +159,28 @@ class report_printscreen_list(report_int):
if fields[f]['type'] in ('one2many','many2many') and line[f]:
line[f] = '( '+tools.ustr(len(line[f])) + ' )'
if fields[f]['type'] == 'float':
if fields[f]['type'] == 'float' and line[f]:
precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2
line[f]='%.2f'%(line[f])
if fields[f]['type'] == 'date' and line[f]:
format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))
d1= mx.DateTime.strptime(line[f],'%Y-%m-%d')
new_d1 = d1.strftime(format)
line[f] = new_d1
if fields[f]['type'] == 'time' and line[f]:
format = str(locale.nl_langinfo(locale.T_FMT))
d1= mx.DateTime.strptime(line[f],'%H:%M:%S')
new_d1 = d1.strftime(format)
line[f] = new_d1
if fields[f]['type'] == 'datetime' and line[f]:
format = str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))+' '+str(locale.nl_langinfo(locale.T_FMT))
d1= mx.DateTime.strptime(line[f],'%Y-%m-%d %H:%M:%S')
new_d1 = d1.strftime(format)
line[f] = new_d1
col = etree.Element("col")
col.set('para','yes')
col.set('tree','no')
@ -169,7 +188,6 @@ class report_printscreen_list(report_int):
col.text = tools.ustr(line[f] or '')
if temp[count] == 1:
tsum[count] = float(tsum[count]) + float(line[f]);
else:
col.text = '/'
node_line.append(col)
@ -197,7 +215,6 @@ class report_printscreen_list(report_int):
lines.append(node_line)
new_doc.append(lines)
styledoc = libxml2.parseFile(os.path.join(tools.config['root_path'],'addons/base/report/custom_new.xsl'))
style = libxslt.parseStylesheetDoc(styledoc)

View File

@ -223,7 +223,7 @@ class _rml_doc(object):
self.canvas.save()
class _rml_canvas(object):
def __init__(self, canvas,localcontext, doc_tmpl=None, doc=None, images={}, path='.', title=None):
def __init__(self, canvas, localcontext, doc_tmpl=None, doc=None, images={}, path='.', title=None):
self.localcontext = localcontext
self.canvas = canvas
self.styles = doc.styles
@ -236,7 +236,7 @@ class _rml_canvas(object):
self.canvas.setTitle(self.title)
def _textual(self, node, x=0, y=0):
rc = utils._process_text(self, node.text or '')
rc = utils._process_text(self, node.text.encode('utf-8') or '')
for n in node:
if n.tag == 'seq':
from reportlab.lib.sequencer import getSequencer
@ -315,7 +315,7 @@ class _rml_canvas(object):
self.canvas.circle(x_cen=utils.unit_get(node.get('x')), y_cen=utils.unit_get(node.get('y')), r=utils.unit_get(node.get('radius')), **utils.attr_get(node, [], {'fill':'bool','stroke':'bool'}))
def _place(self, node):
flows = _rml_flowable(self.doc, images=self.images, path=self.path, title=self.title).render(node)
flows = _rml_flowable(self.doc, self.localcontext, images=self.images, path=self.path, title=self.title).render(node)
infos = utils.attr_get(node, ['x','y','width','height'])
infos['y']+=infos['height']
@ -453,12 +453,12 @@ class _rml_draw(object):
def render(self, canvas, doc):
canvas.saveState()
cnv = _rml_canvas(canvas,self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
cnv = _rml_canvas(canvas, self.localcontext, doc, self.styles, images=self.images, path=self.path, title=self.canvas_title)
cnv.render(self.node)
canvas.restoreState()
class _rml_flowable(object):
def __init__(self,doc,localcontext, images={}, path='.', title=None):
def __init__(self, doc, localcontext, images={}, path='.', title=None):
self.localcontext = localcontext
self.doc = doc
self.styles = doc.styles
@ -474,7 +474,7 @@ class _rml_flowable(object):
if key in ('rml_except', 'rml_loop', 'rml_tag'):
del txt_n.attrib[key]
if True or not self._textual(n).isspace():
txt_n.text = self._textual(n)
txt_n.text = utils.xml2str(self._textual(n))
txt_n.tail = ''
rc1 += etree.tostring(txt_n)
#rc1 += utils._process_text(self, node.tail or '')

View File

@ -41,6 +41,7 @@ import re
import reportlab
from lxml import etree
import copy
import tools
_regex = re.compile('\[\[(.+?)\]\]')
@ -111,7 +112,7 @@ def _process_text(self, txt):
pass
if type(txt)==type('') or type(txt)==type(u''):
txt2 = str2xml(txt)
result += txt2
result += tools.ustr(txt2)
elif (txt is not None) and (txt is not False):
result += str(txt)
return result
@ -119,7 +120,7 @@ def _process_text(self, txt):
def text_get(node):
rc = ''
for node in node.getchildren():
rc = rc + node.text
rc = rc + tools.ustr(node.text)
return rc
units = [

View File

@ -305,7 +305,7 @@ class rml_parse(object):
head_dom = etree.XML(rml_head)
for tag in head_dom.getchildren():
found = rml_dom.find('.//'+tag.tag)
if found is not None:
if found is not None and len(found):
if tag.get('position'):
found.append(tag)
else :

View File

@ -29,7 +29,7 @@ import thread
import threading
import time
import sys
import platform
from tools.translate import _
import addons
import ir
@ -38,7 +38,7 @@ import pooler
import release
import sql_db
import tools
import locale
logging.basicConfig()
class db(netsvc.Service):
@ -60,6 +60,8 @@ class db(netsvc.Service):
self.id = 0
self.id_protect = threading.Semaphore()
self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
def create(self, password, db_name, demo, lang, user_password='admin'):
security.check_super(password)
self.id_protect.acquire()
@ -169,17 +171,28 @@ class db(netsvc.Service):
sql_db.close_db('template1')
return True
def _set_pg_psw_env_var(self):
if os.name == 'nt' and not os.environ.get('PGPASSWORD', ''):
os.environ['PGPASSWORD'] = tools.config['db_password']
self._pg_psw_env_var_is_set = True
def _unset_pg_psw_env_var(self):
if os.name == 'nt' and self._pg_psw_env_var_is_set:
os.environ['PGPASSWORD'] = ''
def dump(self, password, db_name):
security.check_super(password)
logger = netsvc.Logger()
self._set_pg_psw_env_var()
cmd = ['pg_dump', '--format=c', '--no-owner']
if tools.config['db_user']:
cmd.append('--username=' + tools.config['db_user'])
if tools.config['db_host']:
cmd.append('--host=' + tools.config['db_host'])
if tools.config['db_port']:
cmd.append('--port=' + tools.config['db_port'])
cmd.append('--port=' + str(tools.config['db_port']))
cmd.append(db_name)
stdin, stdout = tools.exec_pg_command_pipe(*tuple(cmd))
@ -192,12 +205,17 @@ class db(netsvc.Service):
raise Exception, "Couldn't dump database"
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'DUMP DB: %s' % (db_name))
self._unset_pg_psw_env_var()
return base64.encodestring(data)
def restore(self, password, db_name, data):
security.check_super(password)
logger = netsvc.Logger()
self._set_pg_psw_env_var()
if self.db_exist(db_name):
logger.notifyChannel("web-services", netsvc.LOG_WARNING,
'RESTORE DB: %s already exists' % (db_name,))
@ -218,7 +236,7 @@ class db(netsvc.Service):
if tools.config['db_host']:
cmd.append('--host=' + tools.config['db_host'])
if tools.config['db_port']:
cmd.append('--port=' + tools.config['db_port'])
cmd.append('--port=' + str(tools.config['db_port']))
cmd.append('--dbname=' + db_name)
args2 = tuple(cmd)
@ -238,6 +256,9 @@ class db(netsvc.Service):
raise Exception, "Couldn't restore database"
logger.notifyChannel("web-services", netsvc.LOG_INFO,
'RESTORE DB: %s' % (db_name))
self._unset_pg_psw_env_var()
return True
def rename(self, password, old_name, new_name):
@ -505,27 +526,34 @@ GNU Public Licence.
l.notifyChannel('migration', netsvc.LOG_ERROR, tb_s)
raise
def get_server_environment(self,lang=False):
def get_server_environment(self):
try:
if '.bzr' in os.listdir((os.getcwd()[0:-3])):
fp = open(os.path.join(os.getcwd()[0:-3],'.bzr/branch/last-revision'))
rev_no = fp.read()
fp.close()
else:
rev_no = 'Bazaar Not Installed !'
except:
rev_no = 'Bazaar Not Installed !'
if not lang:
lang = os.environ.get('LANG', '').split('.')[0]
environment = 'Environment_Information : \n' \
'Operating System : %s\n' \
'PlatForm : %s\n' \
'Operating System Version : %s\n' \
'Python Version : %s\n'\
'Locale : %s\n' \
'OpenERP-Server Version : %s\n'\
'OpenERP-Server Last Revision ID : %s' \
%(os.name,sys.platform,str(sys.version.split('\n')[1]),str(sys.version[0:5]), lang, release.version,rev_no)
rev_id = os.popen('bzr revision-info').read()
except Exception,e:
rev_id = 'Exception: %s\n' % (tools.ustr(e))
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\n'\
'Last revision No. & ID : %s'\
%(platform.release(), platform.version(), platform.architecture()[0],
os_lang, platform.python_version(),release.version,rev_id)
return environment
common()
@ -660,7 +688,6 @@ class report_spool(netsvc.Service):
tb = sys.exc_info()
tb_s = "".join(traceback.format_exception(*tb))
logger = netsvc.Logger()
logger.notifyChannel('web-services', netsvc.LOG_ERROR,common().get_server_environment(context.get('lang',False)))
logger.notifyChannel('web-services', netsvc.LOG_ERROR,
'Exception: %s\n%s' % (str(exception), tb_s))
self._reports[id]['exception'] = ExceptionWithTraceback(tools.exception_to_unicode(exception), tb)

View File

@ -98,7 +98,9 @@ def amount_to_text(number, currency):
cents_number = int(number * 100) % 100
cents_name = (cents_number > 1) and 'cents' or 'cent'
cents = _100_to_text(cents_number)
cents = cents_number and '%s %s' % (cents, cents_name) or ''
cents = cents_number and '%s %s' % (cents.lower(), cents_name) or ''
if cents:
lacs += ' and %s' % (cents, )
return lacs

View File

@ -883,7 +883,7 @@ def convert_xml_import(cr, module, xmlfile, idref=None, mode='init', noupdate=Fa
except Exception, e:
logger = netsvc.Logger()
logger.notifyChannel('init', netsvc.LOG_ERROR, 'The XML file does not fit the required schema !')
logger.notifyChannel('init', netsvc.LOG_ERROR, relaxng.error_log.last_error)
logger.notifyChannel('init', netsvc.LOG_ERROR, tools.ustr(relaxng.error_log.last_error))
raise
if idref is None:

View File

@ -672,9 +672,9 @@ class cache(object):
if time.time()-self.timeout > self.lasttime:
self.lasttime = time.time()
t = time.time()-self.timeout
for key in self.cache.keys():
if self.cache[key][1]<t:
del self.cache[key]
old_keys = [key for key in self.cache if self.cache[key][1] < t]
for key in old_keys:
del self.cache[key]
kwargs2 = self._unify_args(*args, **kwargs)

View File

@ -598,20 +598,28 @@ def trans_generate(lang, modules, dbname=None):
modobj = pool.get('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']))
if tools.config['root_path'] in tools.config['addons_path'] :
path_list = [tools.config['root_path']]
else :
path_list = [tools.config['root_path'],tools.config['addons_path']]
for root, dirs, files in tools.osutil.walksymlinks(tools.config['root_path']):
for fname in fnmatch.filter(files, '*.py'):
fabsolutepath = join(root, fname)
frelativepath = fabsolutepath[len(tools.config['root_path'])+1:]
module = get_module_from_path(frelativepath)
is_mod_installed = module in installed_modules
if (('all' in modules) or (module in modules)) and is_mod_installed:
code_string = tools.file_open(fabsolutepath, subdir='').read()
iter = re.finditer(
'[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)',
code_string, re.M)
for i in iter:
push_translation(module, 'code', frelativepath, 0, encode(i.group(1)))
for path in path_list:
for root, dirs, files in tools.osutil.walksymlinks(path):
for fname in fnmatch.filter(files, '*.py'):
fabsolutepath = join(root, fname)
frelativepath = fabsolutepath[len(path):]
module = get_module_from_path(frelativepath)
is_mod_installed = module in installed_modules
if (('all' in modules) or (module in modules)) and is_mod_installed:
code_string = tools.file_open(fabsolutepath, subdir='').read()
iter = re.finditer('[^a-zA-Z0-9_]_\([\s]*["\'](.+?)["\'][\s]*\)',
code_string, re.S)
if module in installed_modules :
frelativepath =str("addons"+frelativepath)
for i in iter:
push_translation(module, 'code', frelativepath, 0, encode(i.group(1)))
out = [["module","type","name","res_id","src","value"]] # header

View File

@ -52,7 +52,7 @@ class workflow_service(netsvc.Service):
cr.execute('select instance_id from wkf_triggers where res_id=%s and model=%s', (res_id,res_type))
res = cr.fetchall()
for (instance_id,) in res:
cr.execute('select uid,res_type,res_id from wkf_instance where id=%s', (instance_id,))
cr.execute('select %s,res_type,res_id from wkf_instance where id=%s', (uid, instance_id,))
ident = cr.fetchone()
instance.update(cr, instance_id, ident)

View File

@ -35,8 +35,10 @@ import glob
from distutils.core import setup, Command
from distutils.command.install import install
has_py2exe = False
if os.name == 'nt':
import py2exe
has_py2exe = True
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), "bin"))
@ -174,6 +176,7 @@ options = {
"py2exe": {
"compressed": 1,
"optimize": 2,
"dist_dir": 'dist',
"packages": ["lxml", "lxml.builder", "lxml._elementpath", "lxml.etree",
"lxml.objectify", "decimal", "xml", "xml.dom", "xml.xpath",
"encodings","mx.DateTime","wizard","pychart","PIL", "pyparsing",
@ -220,7 +223,30 @@ setup(name = name,
options = options,
)
#
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
if has_py2exe:
# Sometime between pytz-2008a and pytz-2008i common_timezones started to
# include only names of zones with a corresponding data file in zoneinfo.
# pytz installs the zoneinfo directory tree in the same directory
# as the pytz/__init__.py file. These data files are loaded using
# pkg_resources.resource_stream. py2exe does not copy this to library.zip so
# resource_stream can't find the files and common_timezones is empty when
# read in the py2exe executable.
# This manually copies zoneinfo into the zip. See also
# http://code.google.com/p/googletransitdatafeed/issues/detail?id=121
import pytz
import zipfile
# Make sure the layout of pytz hasn't changed
assert (pytz.__file__.endswith('__init__.pyc') or
pytz.__file__.endswith('__init__.py')), pytz.__file__
zoneinfo_dir = os.path.join(os.path.dirname(pytz.__file__), 'zoneinfo')
# '..\\Lib\\pytz\\__init__.py' -> '..\\Lib'
disk_basedir = os.path.dirname(os.path.dirname(pytz.__file__))
zipfile_path = os.path.join(options['py2exe']['dist_dir'], 'library.zip')
z = zipfile.ZipFile(zipfile_path, 'a')
for absdir, directories, filenames in os.walk(zoneinfo_dir):
assert absdir.startswith(disk_basedir), (absdir, disk_basedir)
zip_dir = absdir[len(disk_basedir):]
for f in filenames:
z.write(os.path.join(absdir, f), os.path.join(zip_dir, f))
z.close()