[FIX] replaced <TAB> with four white space.

bzr revid: hmo@tinyerp.com-20091124144405-9mzd91chohvf0uu7
This commit is contained in:
Harry (Open ERP) 2009-11-24 20:14:05 +05:30
parent dda5ed6bb1
commit d8ce3f1e2a
24 changed files with 843 additions and 843 deletions

View File

@ -52,10 +52,10 @@ sys.path.insert(1, _ad)
ad_cnt=1
for adp in ad_paths:
if adp != _ad:
sys.path.insert(ad_cnt, adp)
ad_cnt+=1
sys.path.insert(ad_cnt, adp)
ad_cnt+=1
ad_paths.append(_ad) # for get_module_path
ad_paths.append(_ad) # for get_module_path
# Modules already loaded
loaded = []
@ -289,7 +289,7 @@ def get_modules():
plist = []
for ad in ad_paths:
plist.extend(listdir(ad))
plist.extend(listdir(ad))
return list(set(plist))
def get_modules_with_version():
@ -318,7 +318,7 @@ def upgrade_graph(graph, cr, module_list, force=None):
mod_path = get_module_path(module)
terp_file = get_module_resource(module, '__terp__.py')
if not mod_path or not terp_file:
logger.notifyChannel('init', netsvc.LOG_WARNING, 'module %s: not installable' % (module))
logger.notifyChannel('init', netsvc.LOG_WARNING, 'module %s: not installable' % (module))
cr.execute("update ir_module_module set state=%s where name=%s", ('uninstallable', module))
continue

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#

View File

@ -47,15 +47,15 @@ class ir_sequence(osv.osv):
'number_next': fields.integer('Next Number', required=True),
'number_increment': fields.integer('Increment Number', required=True),
'padding' : fields.integer('Number padding', required=True),
'condition': fields.char('Condition', size=250, help="If set, sequence will only be used in case this python expression matches, and will precede other sequences."),
'weight': fields.integer('Weight',required=True, help="If two sequences match, the highest weight will be used.")
'condition': fields.char('Condition', size=250, help="If set, sequence will only be used in case this python expression matches, and will precede other sequences."),
'weight': fields.integer('Weight',required=True, help="If two sequences match, the highest weight will be used.")
}
_defaults = {
'active': lambda *a: True,
'number_increment': lambda *a: 1,
'number_next': lambda *a: 1,
'padding' : lambda *a : 0,
'weight' : lambda *a: 10,
'weight' : lambda *a: 10,
}
def _process(self, s):
@ -74,28 +74,28 @@ class ir_sequence(osv.osv):
}
def get_id(self, cr, uid, sequence_id, test='id=%s', context=None):
if not context:
context = {}
if not context:
context = {}
try:
cr.execute('SELECT id, number_next, prefix, suffix, padding, condition \
FROM ir_sequence \
WHERE '+test+' AND active=%s ORDER BY weight DESC, length(COALESCE(condition,\'\')) DESC \
FOR UPDATE', (sequence_id, True))
FROM ir_sequence \
WHERE '+test+' AND active=%s ORDER BY weight DESC, length(COALESCE(condition,\'\')) DESC \
FOR UPDATE', (sequence_id, True))
for res in cr.dictfetchall():
if res['condition']:
print "ir_seq: %s has condition:" %res['id'], res['condition'],
try:
bo = safe_eval(res['condition'],context)
if not bo:
print "not matched"
continue
except Exception,e:
# it would be normal to have exceptions, because
# the domain may contain errors
print "Exception.\ne:",e
print "Context:", context
continue
print "Matched!"
if res['condition']:
print "ir_seq: %s has condition:" %res['id'], res['condition'],
try:
bo = safe_eval(res['condition'],context)
if not bo:
print "not matched"
continue
except Exception,e:
# it would be normal to have exceptions, because
# the domain may contain errors
print "Exception.\ne:",e
print "Context:", context
continue
print "Matched!"
cr.execute('UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s AND active=%s', (res['id'], True))
if res['number_next']:

View File

@ -147,7 +147,7 @@ showpage'''
inst_id = inst_id[0]
graph = pydot.Dot(fontsize='16', label="""\\\n\\nWorkflow: %s\\n OSV: %s""" % (wkfinfo['name'],wkfinfo['osv']),
size='7.3, 10.1', center='1', ratio='auto', rotate='0', rankdir='TB',
ordering='out'
ordering='out'
)
graph_instance_get(cr, graph, inst_id, data.get('nested', False))
ps_string = graph.create(prog='dot', format='ps')

View File

@ -29,37 +29,37 @@ class ir_module_reference_print(report_sxw.rml_parse):
'time': time,
'findobj': self._object_find,
'objdoc': self._object_doc,
'objdoc2': self._object_doc2,
'objdoc2': self._object_doc2,
'findflds': self._fields_find,
})
def _object_doc(self, obj):
modobj = self.pool.get(obj)
strdocs= modobj.__doc__
if not strdocs:
return None
else:
strdocs=strdocs.strip().splitlines(True)
res = ''
for stre in strdocs:
if not stre or stre.isspace():
break
res += stre
strdocs= modobj.__doc__
if not strdocs:
return None
else:
strdocs=strdocs.strip().splitlines(True)
res = ''
for stre in strdocs:
if not stre or stre.isspace():
break
res += stre
return res
def _object_doc2(self, obj):
modobj = self.pool.get(obj)
strdocs= modobj.__doc__
if not strdocs:
return None
else:
strdocs=strdocs.strip().splitlines(True)
res = []
fou = False
for stre in strdocs:
if fou:
res.append(stre.strip())
elif not stre or stre.isspace():
fou = True
strdocs= modobj.__doc__
if not strdocs:
return None
else:
strdocs=strdocs.strip().splitlines(True)
res = []
fou = False
for stre in strdocs:
if fou:
res.append(stre.strip())
elif not stre or stre.isspace():
fou = True
return res
def _object_find(self, module):

View File

@ -80,7 +80,7 @@ class wizard_export_lang(osv.osv_memory):
) ),
}
_defaults = { 'state': lambda *a: 'choose',
'name': lambda *a: 'lang.tar.gz'
'name': lambda *a: 'lang.tar.gz'
}
wizard_export_lang()

View File

@ -72,10 +72,10 @@ class groups(osv.osv):
return gid
def copy(self, cr, uid, id, default={}, context={}, done_list=[], local=False):
group = self.browse(cr, uid, id, context=context)
group = self.browse(cr, uid, id, context=context)
default = default.copy()
if not 'name' in default:
default['name'] = group['name']
if not 'name' in default:
default['name'] = group['name']
default['name'] = default['name'] + _(' (copy)')
return super(groups, self).copy(cr, uid, id, default, context=context)

View File

@ -39,7 +39,7 @@ import release
class Service(object):
""" Base class for *Local* services
Functionality here is trusted, no authentication.
Functionality here is trusted, no authentication.
"""
_services = {}
def __init__(self, name, audience=''):
@ -48,11 +48,11 @@ class Service(object):
self._methods = {}
def joinGroup(self, name):
raise Exception("No group for local services")
raise Exception("No group for local services")
#GROUPS.setdefault(name, {})[self.__name] = self
def service_exist(self,name):
return Service._services.has_key(name)
return Service._services.has_key(name)
def exportMethod(self, method):
if callable(method):
@ -67,9 +67,9 @@ class Service(object):
class LocalService(object):
""" Proxy for local services.
Any instance of this class will behave like the single instance
of Service(name)
"""
Any instance of this class will behave like the single instance
of Service(name)
"""
def __init__(self, name):
self.__name = name
try:
@ -158,12 +158,12 @@ def init_logger():
dirname = os.path.dirname(logf)
if dirname and not os.path.isdir(dirname):
os.makedirs(dirname)
if tools.config['logrotate'] is not False:
if tools.config['logrotate'] is not False:
handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
elif os.name == 'posix':
handler = logging.handlers.WatchedFileHandler(logf)
else:
handler = logging.handlers.FileHandler(logf)
elif os.name == 'posix':
handler = logging.handlers.WatchedFileHandler(logf)
else:
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)
@ -223,27 +223,27 @@ class Logger(object):
if isinstance(msg, Exception):
msg = tools.exception_to_unicode(msg)
try:
msg = tools.ustr(msg).strip()
try:
msg = tools.ustr(msg).strip()
if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',True):
msg = common().exp_get_server_environment() + "\n" + msg
result = msg.split('\n')
except UnicodeDecodeError:
result = msg.strip().split('\n')
try:
except UnicodeDecodeError:
result = msg.strip().split('\n')
try:
if len(result)>1:
for idx, s in enumerate(result):
level_method('[%02d]: %s' % (idx+1, s,))
elif result:
level_method(result[0])
except IOError,e:
# TODO: perhaps reset the logger streams?
#if logrotate closes our files, we end up here..
pass
except:
# better ignore the exception and carry on..
pass
except IOError,e:
# TODO: perhaps reset the logger streams?
#if logrotate closes our files, we end up here..
pass
except:
# better ignore the exception and carry on..
pass
def set_loglevel(self, level):
log = logging.getLogger()
@ -364,10 +364,10 @@ class OpenERPDispatcher:
self.log('service', service_name)
self.log('method', method)
self.log('params', params)
if hasattr(self,'auth_provider'):
auth = self.auth_provider
else:
auth = None
if hasattr(self,'auth_provider'):
auth = self.auth_provider
else:
auth = None
result = ExportService.getService(service_name).dispatch(method, auth, params)
self.log('result', result)
# We shouldn't marshall None,

View File

@ -56,8 +56,8 @@ __version__ = release.version
# We DON't log this using the standard logger, because we might mess
# with the logfile's permissions. Just do a quick exit here.
if pwd.getpwuid(os.getuid())[0] == 'root' :
sys.stderr.write("Attempted to run OpenERP server as root. This is not good, aborting.\n")
sys.exit(1)
sys.stderr.write("Attempted to run OpenERP server as root. This is not good, aborting.\n")
sys.exit(1)
#----------------------------------------------------------
# get logger
@ -114,13 +114,13 @@ import addons
import service.http_server
if not ( tools.config["stop_after_init"] or \
tools.config["translate_in"] or \
tools.config["translate_out"] ):
service.http_server.init_servers()
service.http_server.init_xmlrpc()
tools.config["translate_in"] or \
tools.config["translate_out"] ):
service.http_server.init_servers()
service.http_server.init_xmlrpc()
import service.netrpc_server
service.netrpc_server.init_servers()
import service.netrpc_server
service.netrpc_server.init_servers()
if tools.config['db_name']:
for db in tools.config['db_name'].split(','):

View File

@ -585,14 +585,14 @@ class many2many(_column):
def get_nice_size(a):
(x,y) = a
if isinstance(y, (int,long)):
size = y
elif y:
y = len(y)
else:
y = 0
return (x, tools.human_size(size))
(x,y) = a
if isinstance(y, (int,long)):
size = y
elif y:
y = len(y)
else:
y = 0
return (x, tools.human_size(size))
# ---------------------------------------------------------
# Function fields

View File

@ -205,9 +205,9 @@ class browse_record(object):
d[n].set_value(self._cr, self._uid, d[n], self, f, lang_obj)
if not datas:
# Where did those ids come from? Perhaps old entries in ir_model_data?
raise except_orm('NoDataError', 'Field %s in %s%s'%(name,self._table_name,str(ids)))
if not datas:
# Where did those ids come from? Perhaps old entries in ir_model_data?
raise except_orm('NoDataError', 'Field %s in %s%s'%(name,self._table_name,str(ids)))
# create browse records for 'remote' objects
for data in datas:
for n, f in ffields:
@ -228,12 +228,12 @@ class browse_record(object):
elif f._type in ('one2many', 'many2many') and len(data[n]):
data[n] = self._list_class([browse_record(self._cr, self._uid, id, self._table.pool.get(f._obj), self._cache, context=self._context, list_class=self._list_class, fields_process=self._fields_process) for id in data[n]], self._context)
self._data[data['id']].update(data)
if not name in self._data[self._id]:
#how did this happen?
logger = netsvc.Logger()
logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Ffields: %s, datas: %s"%(str(fffields),str(datas)))
logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Data: %s, Table: %s"%(str(self._data[self._id]),str(self._table)))
raise AttributeError(_('Unknown attribute %s in %s ') % (str(name),self._table_name))
if not name in self._data[self._id]:
#how did this happen?
logger = netsvc.Logger()
logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Ffields: %s, datas: %s"%(str(fffields),str(datas)))
logger.notifyChannel("browse_record", netsvc.LOG_ERROR,"Data: %s, Table: %s"%(str(self._data[self._id]),str(self._table)))
raise AttributeError(_('Unknown attribute %s in %s ') % (str(name),self._table_name))
return self._data[self._id][name]
def __getattr__(self, name):
@ -671,10 +671,10 @@ class orm_template(object):
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']
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']
row[field[-1][:-3]] = res_id or False
continue
if (len(field) == len(prefix)+1) and \
@ -962,7 +962,7 @@ class orm_template(object):
and getattr(self._columns[f], arg):
res[f][arg] = getattr(self._columns[f], arg)
#TODO: optimize
#TODO: optimize
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US')
if res_trans:
res[f]['string'] = res_trans
@ -1373,7 +1373,7 @@ class orm_template(object):
result['name'] = 'default'
result['field_parent'] = False
result['view_id'] = 0
xarch, xfields = self.__view_look_dom_arch(cr, user, result['arch'], view_id, context=context)
result['arch'] = xarch
result['fields'] = xfields
@ -1454,7 +1454,7 @@ class orm_template(object):
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'read', context=context)
if not fields:
fields = self._columns.keys() + self._inherit_fields.keys()
#FIXME: collect all calls to _get_source into one SQL call.
#FIXME: collect all calls to _get_source into one SQL call.
for lang in langs:
res[lang] = {'code': lang}
for f in fields:
@ -1476,7 +1476,7 @@ class orm_template(object):
def write_string(self, cr, uid, id, langs, vals, context=None):
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'write', context=context)
#FIXME: try to only call the translation in one SQL
#FIXME: try to only call the translation in one SQL
for lang in langs:
for field in vals:
if field in self._columns:
@ -1897,20 +1897,20 @@ class orm(orm_template):
"AND c.oid=a.attrelid " \
"AND a.atttypid=t.oid", (self._table, k))
res = cr.dictfetchall()
if not res and hasattr(f,'oldname'):
cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \
"FROM pg_class c,pg_attribute a,pg_type t " \
"WHERE c.relname=%s " \
"AND a.attname=%s " \
"AND c.oid=a.attrelid " \
"AND a.atttypid=t.oid", (self._table, f.oldname))
res_old = cr.dictfetchall()
logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'trying to rename %s(%s) to %s'% (self._table, f.oldname, k))
if res_old and len(res_old)==1:
cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % ( self._table,f.oldname, k))
res = res_old
res[0]['attname'] = k
if not res and hasattr(f,'oldname'):
cr.execute("SELECT c.relname,a.attname,a.attlen,a.atttypmod,a.attnotnull,a.atthasdef,t.typname,CASE WHEN a.attlen=-1 THEN a.atttypmod-4 ELSE a.attlen END as size " \
"FROM pg_class c,pg_attribute a,pg_type t " \
"WHERE c.relname=%s " \
"AND a.attname=%s " \
"AND c.oid=a.attrelid " \
"AND a.atttypid=t.oid", (self._table, f.oldname))
res_old = cr.dictfetchall()
logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'trying to rename %s(%s) to %s'% (self._table, f.oldname, k))
if res_old and len(res_old)==1:
cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % ( self._table,f.oldname, k))
res = res_old
res[0]['attname'] = k
if not res:
if not isinstance(f, fields.function) or f.store:
@ -2342,7 +2342,7 @@ class orm(orm_template):
continue
if self._columns[f].translate:
ids = map(lambda x: x['id'], res)
#TODO: optimize out of this loop
#TODO: optimize out of this loop
res_trans = self.pool.get('ir.translation')._get_ids(cr, user, self._name+','+f, 'model', context.get('lang', False) or 'en_US', ids)
for r in res:
r[f] = res_trans.get(r['id'], False) or r[f]
@ -2658,7 +2658,7 @@ class orm(orm_template):
'where id in ('+ids_str+')', upd1)
if totranslate:
# TODO: optimize
# TODO: optimize
for f in direct:
if self._columns[f].translate:
src_trans = self.pool.get(self._name).read(cr,user,ids,[f])
@ -3189,7 +3189,7 @@ class orm(orm_template):
data[f] = [(6, 0, data[f])]
trans_obj = self.pool.get('ir.translation')
#TODO: optimize translations
#TODO: optimize translations
trans_name=''
for f in fields:
trans_flag=True

View File

@ -80,7 +80,7 @@ class report_rml(report_int):
'html': self.create_html,
'raw': self.create_raw,
'sxw': self.create_sxw,
'txt': self.create_txt,
'txt': self.create_txt,
'odt': self.create_odt,
'html2html' : self.create_html2html,
'makohtml2html' :self.create_makohtml2html,

View File

@ -22,28 +22,28 @@
CustomTTFonts = [ ('Helvetica',"DejaVu Sans", "DejaVuSans.ttf", 'normal'),
('Helvetica',"DejaVu Sans Bold", "DejaVuSans-Bold.ttf", 'bold'),
('Helvetica',"DejaVu Sans Oblique", "DejaVuSans-Oblique.ttf", 'italic'),
('Helvetica',"DejaVu Sans BoldOblique", "DejaVuSans-BoldOblique.ttf", 'bolditalic'),
('Times',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
('Times',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
('Times',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
('Times',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
('Times-Roman',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
('Times-Roman',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
('Times-Roman',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
('Times-Roman',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
('ZapfDingbats',"DejaVu Serif", "DejaVuSerif.ttf", 'normal'),
('ZapfDingbats',"DejaVu Serif Bold", "DejaVuSerif-Bold.ttf", 'bold'),
('ZapfDingbats',"DejaVu Serif Italic", "DejaVuSerif-Italic.ttf", 'italic'),
('ZapfDingbats',"DejaVu Serif BoldItalic", "DejaVuSerif-BoldItalic.ttf", 'bolditalic'),
('Courier',"FreeMono", "FreeMono.ttf", 'normal'),
('Courier',"FreeMono Bold", "FreeMonoBold.ttf", 'bold'),
('Courier',"FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'),
('Courier',"FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'),]
('Helvetica',"DejaVu Sans Bold", "DejaVuSans-Bold.ttf", 'bold'),
('Helvetica',"DejaVu Sans Oblique", "DejaVuSans-Oblique.ttf", 'italic'),
('Helvetica',"DejaVu Sans BoldOblique", "DejaVuSans-BoldOblique.ttf", 'bolditalic'),
('Times',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
('Times',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
('Times',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
('Times',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
('Times-Roman',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
('Times-Roman',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
('Times-Roman',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
('Times-Roman',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
('ZapfDingbats',"DejaVu Serif", "DejaVuSerif.ttf", 'normal'),
('ZapfDingbats',"DejaVu Serif Bold", "DejaVuSerif-Bold.ttf", 'bold'),
('ZapfDingbats',"DejaVu Serif Italic", "DejaVuSerif-Italic.ttf", 'italic'),
('ZapfDingbats',"DejaVu Serif BoldItalic", "DejaVuSerif-BoldItalic.ttf", 'bolditalic'),
('Courier',"FreeMono", "FreeMono.ttf", 'normal'),
('Courier',"FreeMono Bold", "FreeMonoBold.ttf", 'bold'),
('Courier',"FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'),
('Courier',"FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'),]
def SetCustomFonts(rmldoc):
for name, font, fname, mode in CustomTTFonts:
rmldoc.setTTFontMapping(name, font,fname, mode)
for name, font, fname, mode in CustomTTFonts:
rmldoc.setTTFontMapping(name, font,fname, mode)
#eof
#eof

View File

@ -167,21 +167,21 @@ 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
addMapping(face, 0, 1, fontname) #italic
addMapping(face, 1, 0, fontname) #bold
addMapping(face, 1, 1, fontname) #italic and bold
elif (mode== 'normal') or (mode == 'regular'):
addMapping(face, 0, 0, fontname) #normal
elif (mode == 'italic'):
addMapping(face, 0, 1, fontname) #italic
elif (mode == 'bold'):
addMapping(face, 1, 0, fontname) #bold
elif (mode == 'bolditalic'):
addMapping(face, 1, 1, fontname) #italic and bold
pdfmetrics.registerFont(TTFont(fontname, filename ))
if (mode == 'all'):
addMapping(face, 0, 0, fontname) #normal
addMapping(face, 0, 1, fontname) #italic
addMapping(face, 1, 0, fontname) #bold
addMapping(face, 1, 1, fontname) #italic and bold
elif (mode== 'normal') or (mode == 'regular'):
addMapping(face, 0, 0, fontname) #normal
elif (mode == 'italic'):
addMapping(face, 0, 1, fontname) #italic
elif (mode == 'bold'):
addMapping(face, 1, 0, fontname) #bold
elif (mode == 'bolditalic'):
addMapping(face, 1, 1, fontname) #italic and bold
def _textual_image(self, node):
rc = ''
@ -797,10 +797,10 @@ def parseNode(rml, localcontext = {},fout=None, images={}, path='.',title=None):
r = _rml_doc(node, localcontext, images, path, title=title)
#try to override some font mappings
try:
from customfonts import SetCustomFonts
SetCustomFonts(r)
from customfonts import SetCustomFonts
SetCustomFonts(r)
except:
pass
pass
fp = cStringIO.StringIO()
r.render(fp)
return fp.getvalue()
@ -811,10 +811,10 @@ def parseString(rml, localcontext = {},fout=None, images={}, path='.',title=None
#try to override some font mappings
try:
from customfonts import SetCustomFonts
SetCustomFonts(r)
from customfonts import SetCustomFonts
SetCustomFonts(r)
except:
pass
pass
if fout:
fp = file(fout,'wb')

View File

@ -2,7 +2,7 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
@ -49,93 +49,93 @@ import utils
Font_size= 10.0
def verbose(text):
sys.stderr.write(text+"\n");
sys.stderr.write(text+"\n");
class textbox():
"""A box containing plain text.
It can have an offset, in chars.
Lines can be either text strings, or textbox'es, recursively.
"""
def __init__(self,x=0, y=0):
self.posx = x
self.posy = y
self.lines = []
self.curline = ''
self.endspace = False
def newline(self):
if isinstance(self.curline, textbox):
self.lines.extend(self.curline.renderlines())
else:
self.lines.append(self.curline)
self.curline = ''
def fline(self):
if isinstance(self.curline, textbox):
self.lines.extend(self.curline.renderlines())
elif len(self.curline):
self.lines.append(self.curline)
self.curline = ''
def appendtxt(self,txt):
"""Append some text to the current line.
Mimic the HTML behaviour, where all whitespace evaluates to
a single space """
if not txt:
return
bs = es = False
if txt[0].isspace():
bs = True
if txt[len(txt)-1].isspace():
es = True
if bs and not self.endspace:
self.curline += " "
self.curline += txt.strip().replace("\n"," ").replace("\t"," ")
if es:
self.curline += " "
self.endspace = es
"""A box containing plain text.
It can have an offset, in chars.
Lines can be either text strings, or textbox'es, recursively.
"""
def __init__(self,x=0, y=0):
self.posx = x
self.posy = y
self.lines = []
self.curline = ''
self.endspace = False
def newline(self):
if isinstance(self.curline, textbox):
self.lines.extend(self.curline.renderlines())
else:
self.lines.append(self.curline)
self.curline = ''
def fline(self):
if isinstance(self.curline, textbox):
self.lines.extend(self.curline.renderlines())
elif len(self.curline):
self.lines.append(self.curline)
self.curline = ''
def appendtxt(self,txt):
"""Append some text to the current line.
Mimic the HTML behaviour, where all whitespace evaluates to
a single space """
if not txt:
return
bs = es = False
if txt[0].isspace():
bs = True
if txt[len(txt)-1].isspace():
es = True
if bs and not self.endspace:
self.curline += " "
self.curline += txt.strip().replace("\n"," ").replace("\t"," ")
if es:
self.curline += " "
self.endspace = es
def rendertxt(self,xoffset=0):
result = ''
lineoff = ""
for i in range(self.posy):
result +="\n"
for i in range(self.posx+xoffset):
lineoff+=" "
for l in self.lines:
result+= lineoff+ l +"\n"
return result
def renderlines(self,pad=0):
"""Returns a list of lines, from the current object
pad: all lines must be at least pad characters.
"""
result = []
lineoff = ""
for i in range(self.posx):
lineoff+=" "
for l in self.lines:
lpad = ""
if pad and len(l) < pad :
for i in range(pad - len(l)):
lpad += " "
#elif pad and len(l) > pad ?
result.append(lineoff+ l+lpad)
return result
def haplines(self,arr,offset,cc= ''):
""" Horizontaly append lines
"""
while (len(self.lines) < len(arr)):
self.lines.append("")
for i in range(len(self.lines)):
while (len(self.lines[i]) < offset):
self.lines[i] += " "
for i in range(len(arr)):
self.lines[i] += cc +arr[i]
def rendertxt(self,xoffset=0):
result = ''
lineoff = ""
for i in range(self.posy):
result +="\n"
for i in range(self.posx+xoffset):
lineoff+=" "
for l in self.lines:
result+= lineoff+ l +"\n"
return result
def renderlines(self,pad=0):
"""Returns a list of lines, from the current object
pad: all lines must be at least pad characters.
"""
result = []
lineoff = ""
for i in range(self.posx):
lineoff+=" "
for l in self.lines:
lpad = ""
if pad and len(l) < pad :
for i in range(pad - len(l)):
lpad += " "
#elif pad and len(l) > pad ?
result.append(lineoff+ l+lpad)
return result
def haplines(self,arr,offset,cc= ''):
""" Horizontaly append lines
"""
while (len(self.lines) < len(arr)):
self.lines.append("")
for i in range(len(self.lines)):
while (len(self.lines[i]) < offset):
self.lines[i] += " "
for i in range(len(arr)):
self.lines[i] += cc +arr[i]
class _flowable(object):
def __init__(self, template, doc,localcontext):
@ -143,8 +143,8 @@ class _flowable(object):
'1title': self._tag_title,
'1spacer': self._tag_spacer,
'para': self._tag_para,
'font': self._tag_font,
'section': self._tag_section,
'font': self._tag_font,
'section': self._tag_section,
'1nextFrame': self._tag_next_frame,
'blockTable': self._tag_table,
'1pageBreak': self._tag_page_break,
@ -152,15 +152,15 @@ class _flowable(object):
}
self.template = template
self.doc = doc
self.localcontext = localcontext
self.nitags = []
self.tbox = None
self.localcontext = localcontext
self.nitags = []
self.tbox = None
def warn_nitag(self,tag):
if tag not in self.nitags:
verbose("Unknown tag \"%s\", please implement it." % tag)
self.nitags.append(tag)
if tag not in self.nitags:
verbose("Unknown tag \"%s\", please implement it." % tag)
self.nitags.append(tag)
def _tag_page_break(self, node):
return "\f"
@ -182,79 +182,79 @@ class _flowable(object):
return "\n"*length
def _tag_table(self, node):
self.tb.fline()
saved_tb = self.tb
self.tb = None
sizes = None
self.tb.fline()
saved_tb = self.tb
self.tb = None
sizes = None
if node.get('colWidths'):
sizes = map(lambda x: utils.unit_get(x), node.get('colWidths').split(','))
trs = []
for n in utils._child_get(node,self):
if n.tag == 'tr':
tds = []
for m in utils._child_get(n,self):
if m.tag == 'td':
self.tb = textbox()
self.rec_render_cnodes(m)
tds.append(self.tb)
self.tb = None
if len(tds):
trs.append(tds)
if not sizes:
verbose("computing table sizes..")
for tds in trs:
trt = textbox()
off=0
for i in range(len(tds)):
p = int(sizes[i]/Font_size)
trl = tds[i].renderlines(pad=p)
trt.haplines(trl,off)
off += sizes[i]/Font_size
saved_tb.curline = trt
saved_tb.fline()
self.tb = saved_tb
trs = []
for n in utils._child_get(node,self):
if n.tag == 'tr':
tds = []
for m in utils._child_get(n,self):
if m.tag == 'td':
self.tb = textbox()
self.rec_render_cnodes(m)
tds.append(self.tb)
self.tb = None
if len(tds):
trs.append(tds)
if not sizes:
verbose("computing table sizes..")
for tds in trs:
trt = textbox()
off=0
for i in range(len(tds)):
p = int(sizes[i]/Font_size)
trl = tds[i].renderlines(pad=p)
trt.haplines(trl,off)
off += sizes[i]/Font_size
saved_tb.curline = trt
saved_tb.fline()
self.tb = saved_tb
return
def _tag_para(self, node):
#TODO: styles
self.rec_render_cnodes(node)
self.tb.newline()
#TODO: styles
self.rec_render_cnodes(node)
self.tb.newline()
def _tag_section(self, node):
#TODO: styles
self.rec_render_cnodes(node)
self.tb.newline()
#TODO: styles
self.rec_render_cnodes(node)
self.tb.newline()
def _tag_font(self, node):
"""We do ignore fonts.."""
self.rec_render_cnodes(node)
"""We do ignore fonts.."""
self.rec_render_cnodes(node)
def rec_render_cnodes(self,node):
self.tb.appendtxt(utils._process_text(self, node.text or ''))
for n in utils._child_get(node,self):
self.rec_render(n)
self.tb.appendtxt(utils._process_text(self, node.tail or ''))
self.rec_render(n)
self.tb.appendtxt(utils._process_text(self, node.tail or ''))
def rec_render(self,node):
""" Recursive render: fill outarr with text of current node
"""
if node.tag != None:
if node.tag in self._tags:
self._tags[node.tag](node)
else:
self.warn_nitag(node.tag)
"""
if node.tag != None:
if node.tag in self._tags:
self._tags[node.tag](node)
else:
self.warn_nitag(node.tag)
def render(self, node):
self.tb= textbox()
self.tb= textbox()
#result = self.template.start()
#result += self.template.frame_start()
self.rec_render_cnodes(node)
self.rec_render_cnodes(node)
#result += self.template.frame_stop()
#result += self.template.end()
result = self.tb.rendertxt()
del self.tb
result = self.tb.rendertxt()
del self.tb
return result
class _rml_tmpl_tag(object):
@ -274,12 +274,12 @@ class _rml_tmpl_frame(_rml_tmpl_tag):
self.width = width
self.posx = posx
def tag_start(self):
return "frame start"
return "frame start"
return '<table border="0" width="%d"><tr><td width="%d">&nbsp;</td><td>' % (self.width+self.posx,self.posx)
def tag_end(self):
return True
def tag_stop(self):
return "frame stop"
return "frame stop"
return '</td></tr></table><br/>'
def tag_mergeable(self):
return False
@ -301,7 +301,7 @@ class _rml_tmpl_draw_string(_rml_tmpl_tag):
self.pos = [(self.posx, self.posy, align, utils.text_get(node), style.get('td'), style.font_size_get('td'))]
def tag_start(self):
return "draw string \"%s\" @(%d,%d)..\n" %("txt",self.posx,self.posy)
return "draw string \"%s\" @(%d,%d)..\n" %("txt",self.posx,self.posy)
self.pos.sort()
res = '\\table ...'
posx = 0
@ -335,7 +335,7 @@ class _rml_tmpl_draw_lines(_rml_tmpl_tag):
self.style = style.get('hr')
def tag_start(self):
return "draw lines..\n"
return "draw lines..\n"
if self.ok:
return '<table border="0" cellpadding="0" cellspacing="0" width="%d"><tr><td width="%d"></td><td><hr width="100%%" style="margin:0px; %s"></td></tr></table>' % (self.posx+self.width,self.posx,self.style)
else:
@ -475,7 +475,7 @@ class _rml_template(object):
return ''
def end(self):
return "template end\n"
return "template end\n"
result = ''
while not self.loop:
result += self.frame_start()
@ -498,16 +498,16 @@ class _rml_doc(object):
#self.styles = _rml_styles(el,self.localcontext)
el = self.etree.findall('template')
self.result =""
self.result =""
if len(el):
pt_obj = _rml_template(self.localcontext, out, el[0], self)
stories = utils._child_get(self.etree, self, 'story')
for story in stories:
if self.result:
self.result += '\f'
f = _flowable(pt_obj,story,self.localcontext)
self.result += f.render(story)
del f
for story in stories:
if self.result:
self.result += '\f'
f = _flowable(pt_obj,story,self.localcontext)
self.result += f.render(story)
del f
else:
self.result = "<cannot render w/o template>"
self.result += '\n'

View File

@ -46,15 +46,15 @@ except ImportError:
fcntl = None
try:
from ssl import SSLError
from ssl import SSLError
except ImportError:
class SSLError(Exception): pass
class SSLError(Exception): pass
class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer):
""" A threaded httpd server, with all the necessary functionality for us.
It also inherits the xml-rpc dispatcher, so that some xml-rpc functions
will be available to the request handler
It also inherits the xml-rpc dispatcher, so that some xml-rpc functions
will be available to the request handler
"""
encoding = None
allow_none = False
@ -81,46 +81,46 @@ class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer)
""" Override the error handler
"""
import traceback
netsvc.Logger().notifyChannel("init", netsvc.LOG_ERROR,"Server error in request from %s:\n%s" %
(client_address,traceback.format_exc()))
netsvc.Logger().notifyChannel("init", netsvc.LOG_ERROR,"Server error in request from %s:\n%s" %
(client_address,traceback.format_exc()))
class MultiHandler2(MultiHTTPHandler):
def log_message(self, format, *args):
netsvc.Logger().notifyChannel('http',netsvc.LOG_DEBUG,format % args)
netsvc.Logger().notifyChannel('http',netsvc.LOG_DEBUG,format % args)
def log_error(self, format, *args):
netsvc.Logger().notifyChannel('http',netsvc.LOG_ERROR,format % args)
netsvc.Logger().notifyChannel('http',netsvc.LOG_ERROR,format % args)
class SecureMultiHandler2(SecureMultiHTTPHandler):
def log_message(self, format, *args):
netsvc.Logger().notifyChannel('https',netsvc.LOG_DEBUG,format % args)
netsvc.Logger().notifyChannel('https',netsvc.LOG_DEBUG,format % args)
def getcert_fnames(self):
tc = tools.config
fcert = tc.get_misc('httpsd','sslcert', 'ssl/server.cert')
fkey = tc.get_misc('httpsd','sslkey', 'ssl/server.key')
return (fcert,fkey)
fkey = tc.get_misc('httpsd','sslkey', 'ssl/server.key')
return (fcert,fkey)
def log_message(self, format, *args):
netsvc.Logger().notifyChannel('http',netsvc.LOG_DEBUG,format % args)
netsvc.Logger().notifyChannel('http',netsvc.LOG_DEBUG,format % args)
def log_error(self, format, *args):
netsvc.Logger().notifyChannel('http',netsvc.LOG_ERROR,format % args)
netsvc.Logger().notifyChannel('http',netsvc.LOG_ERROR,format % args)
class HttpDaemon(threading.Thread, netsvc.Server):
def __init__(self, interface, port):
threading.Thread.__init__(self)
netsvc.Server.__init__(self)
netsvc.Server.__init__(self)
self.__port = port
self.__interface = interface
try:
self.server = ThreadedHTTPServer((interface, port), MultiHandler2)
self.server.vdirs = []
self.server.logRequests = True
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"starting HTTP service at %s port %d" % (interface or '0.0.0.0', port,))
self.server.vdirs = []
self.server.logRequests = True
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"starting HTTP service at %s port %d" % (interface or '0.0.0.0', port,))
except Exception, e:
netsvc.Logger().notifyChannel('httpd', netsvc.LOG_CRITICAL, "Error occur when starting the server daemon: %s" % (e,))
raise
@ -146,16 +146,16 @@ class HttpDaemon(threading.Thread, netsvc.Server):
class HttpSDaemon(threading.Thread, netsvc.Server):
def __init__(self, interface, port):
threading.Thread.__init__(self)
netsvc.Server.__init__(self)
netsvc.Server.__init__(self)
self.__port = port
self.__interface = interface
try:
self.server = ThreadedHTTPServer((interface, port), SecureMultiHandler2)
self.server.vdirs = []
self.server.logRequests = True
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"starting HTTPS service at %s port %d" % (interface or '0.0.0.0', port,))
self.server = ThreadedHTTPServer((interface, port), SecureMultiHandler2)
self.server.vdirs = []
self.server.logRequests = True
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"starting HTTPS service at %s port %d" % (interface or '0.0.0.0', port,))
except SSLError, e:
netsvc.Logger().notifyChannel('httpd-ssl', netsvc.LOG_CRITICAL, "Can not load the certificate and/or the private key files")
raise
@ -184,32 +184,32 @@ httpd = None
httpsd = None
def init_servers():
global httpd, httpsd
if tools.config.get_misc('httpd','enable', True):
httpd = HttpDaemon(tools.config.get_misc('httpd','interface', ''), \
tools.config.get_misc('httpd','port', 8069))
global httpd, httpsd
if tools.config.get_misc('httpd','enable', True):
httpd = HttpDaemon(tools.config.get_misc('httpd','interface', ''), \
tools.config.get_misc('httpd','port', 8069))
if tools.config.get_misc('httpsd','enable', False):
httpsd = HttpSDaemon(tools.config.get_misc('httpsd','interface', ''), \
tools.config.get_misc('httpsd','port', 8071))
if tools.config.get_misc('httpsd','enable', False):
httpsd = HttpSDaemon(tools.config.get_misc('httpsd','interface', ''), \
tools.config.get_misc('httpsd','port', 8071))
def reg_http_service(hts, secure_only = False):
""" Register some handler to httpd.
hts must be an HTTPDir
"""
global httpd, httpsd
if not isinstance(hts, HTTPDir):
raise Exception("Wrong class for http service")
if httpd and not secure_only:
httpd.server.vdirs.append(hts)
if httpsd:
httpsd.server.vdirs.append(hts)
if (not httpd) and (not httpsd):
netsvc.Logger().notifyChannel('httpd',netsvc.LOG_WARNING,"No httpd available to register service %s" % hts.path)
return
""" Register some handler to httpd.
hts must be an HTTPDir
"""
global httpd, httpsd
if not isinstance(hts, HTTPDir):
raise Exception("Wrong class for http service")
if httpd and not secure_only:
httpd.server.vdirs.append(hts)
if httpsd:
httpsd.server.vdirs.append(hts)
if (not httpd) and (not httpsd):
netsvc.Logger().notifyChannel('httpd',netsvc.LOG_WARNING,"No httpd available to register service %s" % hts.path)
return
import SimpleXMLRPCServer
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
@ -223,7 +223,7 @@ class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCSer
raise xmlrpclib.Fault(tools.exception_to_unicode(e.exception), e.traceback)
def log_message(self, format, *args):
netsvc.Logger().notifyChannel('xmlrpc',netsvc.LOG_DEBUG_RPC,format % args)
netsvc.Logger().notifyChannel('xmlrpc',netsvc.LOG_DEBUG_RPC,format % args)
def handle(self):
pass
@ -233,87 +233,87 @@ class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCSer
def setup(self):
self.connection = dummyconn()
if not len(XMLRPCRequestHandler.rpc_paths):
XMLRPCRequestHandler.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys())
if not len(XMLRPCRequestHandler.rpc_paths):
XMLRPCRequestHandler.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys())
pass
def init_xmlrpc():
if not tools.config.get_misc('xmlrpc','enable', True):
return
reg_http_service(HTTPDir('/xmlrpc/',XMLRPCRequestHandler))
# Example of http file serving:
# reg_http_service(HTTPDir('/test/',HTTPHandler))
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"Registered XML-RPC over HTTP")
if not tools.config.get_misc('xmlrpc','enable', True):
return
reg_http_service(HTTPDir('/xmlrpc/',XMLRPCRequestHandler))
# Example of http file serving:
# reg_http_service(HTTPDir('/test/',HTTPHandler))
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
"Registered XML-RPC over HTTP")
class OerpAuthProxy(AuthProxy):
""" Require basic authentication..
This is a copy of the BasicAuthProxy, which however checks/caches the db
as well.
"""
def __init__(self,provider):
AuthProxy.__init__(self,provider)
self.auth_creds = {}
self.auth_tries = 0
self.last_auth = None
""" Require basic authentication..
This is a copy of the BasicAuthProxy, which however checks/caches the db
as well.
"""
def __init__(self,provider):
AuthProxy.__init__(self,provider)
self.auth_creds = {}
self.auth_tries = 0
self.last_auth = None
def checkRequest(self,handler,path = '/'):
if self.auth_creds:
return True
auth_str = handler.headers.get('Authorization',False)
try:
db = handler.get_db_from_path(path)
print "Got db:",db
except:
if path.startswith('/'):
path = path[1:]
psp= path.split('/')
if len(psp)>1:
db = psp[0]
else:
#FIXME!
self.provider.log("Wrong path: %s, failing auth" %path)
raise AuthRejectedExc("Authorization failed. Wrong sub-path.")
def checkRequest(self,handler,path = '/'):
if self.auth_creds:
return True
auth_str = handler.headers.get('Authorization',False)
try:
db = handler.get_db_from_path(path)
print "Got db:",db
except:
if path.startswith('/'):
path = path[1:]
psp= path.split('/')
if len(psp)>1:
db = psp[0]
else:
#FIXME!
self.provider.log("Wrong path: %s, failing auth" %path)
raise AuthRejectedExc("Authorization failed. Wrong sub-path.")
if auth_str and auth_str.startswith('Basic '):
auth_str=auth_str[len('Basic '):]
(user,passwd) = base64.decodestring(auth_str).split(':')
self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db))
acd = self.provider.authenticate(db,user,passwd,handler.client_address)
if acd != False:
self.auth_creds[db] = acd
self.last_auth=db
return True
if self.auth_tries > 5:
self.provider.log("Failing authorization after 5 requests w/o password")
raise AuthRejectedExc("Authorization failed.")
self.auth_tries += 1
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
if auth_str and auth_str.startswith('Basic '):
auth_str=auth_str[len('Basic '):]
(user,passwd) = base64.decodestring(auth_str).split(':')
self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db))
acd = self.provider.authenticate(db,user,passwd,handler.client_address)
if acd != False:
self.auth_creds[db] = acd
self.last_auth=db
return True
if self.auth_tries > 5:
self.provider.log("Failing authorization after 5 requests w/o password")
raise AuthRejectedExc("Authorization failed.")
self.auth_tries += 1
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
import security
class OpenERPAuthProvider(AuthProvider):
def __init__(self,realm = 'OpenERP User'):
self.realm = realm
def __init__(self,realm = 'OpenERP User'):
self.realm = realm
def setupAuth(self, multi, handler):
if not multi.sec_realms.has_key(self.realm):
multi.sec_realms[self.realm] = OerpAuthProxy(self)
handler.auth_proxy = multi.sec_realms[self.realm]
def setupAuth(self, multi, handler):
if not multi.sec_realms.has_key(self.realm):
multi.sec_realms[self.realm] = OerpAuthProxy(self)
handler.auth_proxy = multi.sec_realms[self.realm]
def authenticate(self, db, user, passwd, client_address):
try:
uid = security.login(db,user,passwd)
if uid is False:
return False
return (user, passwd, db, uid)
except Exception,e:
netsvc.Logger().notifyChannel("auth",netsvc.LOG_DEBUG,"Fail auth:"+ str(e))
return False
def log(self, msg):
netsvc.Logger().notifyChannel("auth",netsvc.LOG_INFO,msg)
def authenticate(self, db, user, passwd, client_address):
try:
uid = security.login(db,user,passwd)
if uid is False:
return False
return (user, passwd, db, uid)
except Exception,e:
netsvc.Logger().notifyChannel("auth",netsvc.LOG_DEBUG,"Fail auth:"+ str(e))
return False
def log(self, msg):
netsvc.Logger().notifyChannel("auth",netsvc.LOG_INFO,msg)
#eof

View File

@ -141,23 +141,23 @@ class TinySocketServerThread(threading.Thread,netsvc.Server):
return False
def stats(self):
res = "Net-RPC: " + ( (self.running and "running") or "stopped")
i = 0
for t in self.threads:
i += 1
res += "\nNet-RPC #%d: %s " % (i, t.name)
if t.isAlive():
res += "running"
else:
res += "finished"
if t.sock:
res += ", socket"
return res
res = "Net-RPC: " + ( (self.running and "running") or "stopped")
i = 0
for t in self.threads:
i += 1
res += "\nNet-RPC #%d: %s " % (i, t.name)
if t.isAlive():
res += "running"
else:
res += "finished"
if t.sock:
res += ", socket"
return res
netrpcd = None
def init_servers():
global netrpcd
if tools.config.get_misc('netrpcd','enable', True):
netrpcd = TinySocketServerThread(tools.config.get_misc('netrpcd','interface', ''), \
tools.config.get_misc('netrpcd','port', 8070))
global netrpcd
if tools.config.get_misc('netrpcd','enable', True):
netrpcd = TinySocketServerThread(tools.config.get_misc('netrpcd','interface', ''), \
tools.config.get_misc('netrpcd','port', 8070))

View File

@ -51,23 +51,23 @@ class db(netsvc.ExportService):
self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
def dispatch(self, method, auth, params):
if method in [ 'create', 'get_progress', 'drop', 'dump',
'restore', 'rename',
'change_admin_password', 'migrate_databases' ]:
passwd = params[0]
params = params[1:]
security.check_super(passwd)
elif method in [ 'db_exist', 'list', 'list_lang', 'server_version' ]:
# params = params
# No security check for these methods
pass
else:
raise KeyError("Method not found: %s" % method)
fn = getattr(self, 'exp_'+method)
return fn(*params)
if method in [ 'create', 'get_progress', 'drop', 'dump',
'restore', 'rename',
'change_admin_password', 'migrate_databases' ]:
passwd = params[0]
params = params[1:]
security.check_super(passwd)
elif method in [ 'db_exist', 'list', 'list_lang', 'server_version' ]:
# params = params
# No security check for these methods
pass
else:
raise KeyError("Method not found: %s" % method)
fn = getattr(self, 'exp_'+method)
return fn(*params)
def new_dispatch(self,method,auth,params):
pass
pass
def exp_create(self, db_name, demo, lang, user_password='admin'):
self.id_protect.acquire()
@ -366,15 +366,15 @@ class _ObjectService(netsvc.ExportService):
"A common base class for those who have fn(db, uid, password,...) "
def common_dispatch(self, method, auth, params):
(db, uid, passwd ) = params[0:3]
params = params[3:]
security.check(db,uid,passwd)
cr = pooler.get_db(db).cursor()
fn = getattr(self, 'exp_'+method)
res = fn(cr, uid, *params)
cr.commit()
cr.close()
return res
(db, uid, passwd ) = params[0:3]
params = params[3:]
security.check(db,uid,passwd)
cr = pooler.get_db(db).cursor()
fn = getattr(self, 'exp_'+method)
res = fn(cr, uid, *params)
cr.commit()
cr.close()
return res
class common(_ObjectService):
def __init__(self,name="common"):
@ -382,36 +382,36 @@ class common(_ObjectService):
self.joinGroup("web-services")
def dispatch(self, method, auth, params):
logger = netsvc.Logger()
if method in [ 'ir_set','ir_del', 'ir_get' ]:
return self.common_dispatch(method,auth,params)
if method == 'login':
# At this old dispatcher, we do NOT update the auth proxy
res = security.login(params[0], params[1], params[2])
msg = res and 'successful login' or 'bad login or password'
# TODO log the client ip address..
logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, params[1], params[0].lower()))
return res or False
elif method == 'logout':
if auth:
auth.logout(params[1])
logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db))
return True
elif method in ['about', 'timezone_get', 'get_server_environment', 'login_message', 'get_stats' ]:
pass
elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel']:
passwd = params[0]
params = params[1:]
security.check_super(passwd)
else:
raise Exception("Method not found: %s" % method)
fn = getattr(self, 'exp_'+method)
return fn(*params)
logger = netsvc.Logger()
if method in [ 'ir_set','ir_del', 'ir_get' ]:
return self.common_dispatch(method,auth,params)
if method == 'login':
# At this old dispatcher, we do NOT update the auth proxy
res = security.login(params[0], params[1], params[2])
msg = res and 'successful login' or 'bad login or password'
# TODO log the client ip address..
logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, params[1], params[0].lower()))
return res or False
elif method == 'logout':
if auth:
auth.logout(params[1])
logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db))
return True
elif method in ['about', 'timezone_get', 'get_server_environment', 'login_message', 'get_stats' ]:
pass
elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel']:
passwd = params[0]
params = params[1:]
security.check_super(passwd)
else:
raise Exception("Method not found: %s" % method)
fn = getattr(self, 'exp_'+method)
return fn(*params)
def new_dispatch(self,method,auth,params):
pass
pass
def exp_ir_set(self, cr, uid, keys, args, name, value, replace=True, isobject=False):
res = ir.ir_set(cr,uid, keys, args, name, value, replace, isobject)
@ -574,7 +574,7 @@ GNU Public Licence.
def exp_get_stats(self):
import threading
res = "OpenERP server: %d threads\n" % threading.active_count()
res += netsvc.Server.allStats()
res += netsvc.Server.allStats()
return res
common()
@ -585,19 +585,19 @@ class objects_proxy(netsvc.ExportService):
self.joinGroup('web-services')
def dispatch(self, method, auth, params):
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['execute','exec_workflow','obj_list']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
ls = netsvc.LocalService('object_proxy')
fn = getattr(ls, method)
res = fn(db, uid, *params)
return res
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['execute','exec_workflow','obj_list']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
ls = netsvc.LocalService('object_proxy')
fn = getattr(ls, method)
res = fn(db, uid, *params)
return res
def new_dispatch(self,method,auth,params):
pass
pass
objects_proxy()
@ -623,17 +623,17 @@ class wizard(netsvc.ExportService):
self.wiz_uid = {}
def dispatch(self, method, auth, params):
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['execute','create']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
fn = getattr(self, 'exp_'+method)
res = fn(db, uid, *params)
return res
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['execute','create']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
fn = getattr(self, 'exp_'+method)
res = fn(db, uid, *params)
return res
def new_dispatch(self,method,auth,params):
pass
pass
def _execute(self, db, uid, wiz_id, datas, action, context):
self.wiz_datas[wiz_id].update(datas)
@ -685,18 +685,18 @@ class report_spool(netsvc.ExportService):
self.id_protect = threading.Semaphore()
def dispatch(self, method, auth, params):
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['report','report_get']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
fn = getattr(self, 'exp_' + method)
res = fn(db, uid, *params)
return res
(db, uid, passwd ) = params[0:3]
params = params[3:]
if method not in ['report','report_get']:
raise KeyError("Method not supported %s" % method)
security.check(db,uid,passwd)
fn = getattr(self, 'exp_' + method)
res = fn(db, uid, *params)
return res
def new_dispatch(self,method,auth,params):
pass
pass
def exp_report(self, db, uid, object, ids, datas=None, context=None):
if not datas:

View File

@ -37,115 +37,115 @@ from BaseHTTPServer import *
from SimpleHTTPServer import SimpleHTTPRequestHandler
class AuthRequiredExc(Exception):
def __init__(self,atype,realm):
Exception.__init__(self)
self.atype = atype
self.realm = realm
def __init__(self,atype,realm):
Exception.__init__(self)
self.atype = atype
self.realm = realm
class AuthRejectedExc(Exception):
pass
pass
class AuthProvider:
def __init__(self,realm):
self.realm = realm
def __init__(self,realm):
self.realm = realm
def setupAuth(self, multi,handler):
""" Attach an AuthProxy object to handler
"""
pass
def setupAuth(self, multi,handler):
""" Attach an AuthProxy object to handler
"""
pass
def authenticate(self, user, passwd, client_address):
return False
def log(self, msg):
print msg
def authenticate(self, user, passwd, client_address):
return False
def log(self, msg):
print msg
class BasicAuthProvider(AuthProvider):
def setupAuth(self, multi, handler):
if not multi.sec_realms.has_key(self.realm):
multi.sec_realms[self.realm] = BasicAuthProxy(self)
def setupAuth(self, multi, handler):
if not multi.sec_realms.has_key(self.realm):
multi.sec_realms[self.realm] = BasicAuthProxy(self)
class AuthProxy:
""" This class will hold authentication information for a handler,
i.e. a connection
"""
def __init__(self, provider):
self.provider = provider
""" This class will hold authentication information for a handler,
i.e. a connection
"""
def __init__(self, provider):
self.provider = provider
def checkRequest(self,handler,path = '/'):
""" Check if we are allowed to process that request
"""
pass
def checkRequest(self,handler,path = '/'):
""" Check if we are allowed to process that request
"""
pass
class BasicAuthProxy(AuthProxy):
""" Require basic authentication..
"""
def __init__(self,provider):
AuthProxy.__init__(self,provider)
self.auth_creds = None
self.auth_tries = 0
""" Require basic authentication..
"""
def __init__(self,provider):
AuthProxy.__init__(self,provider)
self.auth_creds = None
self.auth_tries = 0
def checkRequest(self,handler,path = '/'):
if self.auth_creds:
return True
auth_str = handler.headers.get('Authorization',False)
if auth_str and auth_str.startswith('Basic '):
auth_str=auth_str[len('Basic '):]
(user,passwd) = base64.decodestring(auth_str).split(':')
self.provider.log("Found user=\"%s\", passwd=\"%s\"" %(user,passwd))
self.auth_creds = self.provider.authenticate(user,passwd,handler.client_address)
if self.auth_creds:
return True
if self.auth_tries > 5:
self.provider.log("Failing authorization after 5 requests w/o password")
raise AuthRejectedExc("Authorization failed.")
self.auth_tries += 1
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
def checkRequest(self,handler,path = '/'):
if self.auth_creds:
return True
auth_str = handler.headers.get('Authorization',False)
if auth_str and auth_str.startswith('Basic '):
auth_str=auth_str[len('Basic '):]
(user,passwd) = base64.decodestring(auth_str).split(':')
self.provider.log("Found user=\"%s\", passwd=\"%s\"" %(user,passwd))
self.auth_creds = self.provider.authenticate(user,passwd,handler.client_address)
if self.auth_creds:
return True
if self.auth_tries > 5:
self.provider.log("Failing authorization after 5 requests w/o password")
raise AuthRejectedExc("Authorization failed.")
self.auth_tries += 1
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
class HTTPHandler(SimpleHTTPRequestHandler):
def __init__(self,request, client_address, server):
SimpleHTTPRequestHandler.__init__(self,request,client_address,server)
# print "Handler for %s inited" % str(client_address)
self.protocol_version = 'HTTP/1.1'
self.connection = dummyconn()
def handle(self):
""" Classes here should NOT handle inside their constructor
"""
pass
def finish(self):
pass
def setup(self):
pass
def __init__(self,request, client_address, server):
SimpleHTTPRequestHandler.__init__(self,request,client_address,server)
# print "Handler for %s inited" % str(client_address)
self.protocol_version = 'HTTP/1.1'
self.connection = dummyconn()
def handle(self):
""" Classes here should NOT handle inside their constructor
"""
pass
def finish(self):
pass
def setup(self):
pass
class HTTPDir:
""" A dispatcher class, like a virtual folder in httpd
"""
def __init__(self,path,handler, auth_provider = None):
self.path = path
self.handler = handler
self.auth_provider = auth_provider
def matches(self, request):
""" Test if some request matches us. If so, return
the matched path. """
if request.startswith(self.path):
return self.path
return False
""" A dispatcher class, like a virtual folder in httpd
"""
def __init__(self,path,handler, auth_provider = None):
self.path = path
self.handler = handler
self.auth_provider = auth_provider
def matches(self, request):
""" Test if some request matches us. If so, return
the matched path. """
if request.startswith(self.path):
return self.path
return False
class noconnection:
""" a class to use instead of the real connection
"""
def makefile(self, mode, bufsize):
return None
""" a class to use instead of the real connection
"""
def makefile(self, mode, bufsize):
return None
class dummyconn:
def shutdown(self, tru):
pass
def shutdown(self, tru):
pass
def _quote_html(html):
return html.replace("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;")
@ -168,7 +168,7 @@ class FixSendError:
self.send_response(code, message)
self.send_header("Content-Type", self.error_content_type)
self.send_header('Connection', 'close')
self.send_header('Content-Length', len(content) or 0)
self.send_header('Content-Length', len(content) or 0)
self.end_headers()
if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
self.wfile.write(content)
@ -176,65 +176,65 @@ class FixSendError:
class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
""" this is a multiple handler, that will dispatch each request
to a nested handler, iff it matches
The handler will also have *one* dict of authentication proxies,
groupped by their realm.
The handler will also have *one* dict of authentication proxies,
groupped by their realm.
"""
protocol_version = "HTTP/1.1"
default_request_version = "HTTP/0.9" # compatibility with py2.5
default_request_version = "HTTP/0.9" # compatibility with py2.5
auth_required_msg = """ <html><head><title>Authorization required</title></head>
<body>You must authenticate to use this service</body><html>\r\r"""
def __init__(self, request, client_address, server):
self.in_handlers = {}
self.sec_realms = {}
SocketServer.StreamRequestHandler.__init__(self,request,client_address,server)
self.log_message("MultiHttpHandler init for %s" %(str(client_address)))
self.in_handlers = {}
self.sec_realms = {}
SocketServer.StreamRequestHandler.__init__(self,request,client_address,server)
self.log_message("MultiHttpHandler init for %s" %(str(client_address)))
def _handle_one_foreign(self,fore, path, auth_provider):
""" This method overrides the handle_one_request for *children*
handlers. It is required, since the first line should not be
read again..
read again..
"""
fore.raw_requestline = "%s %s %s\n" % (self.command, path, self.version)
if not fore.parse_request(): # An error code has been sent, just exit
return
self.request_version = fore.request_version
if auth_provider and auth_provider.realm:
try:
self.sec_realms[auth_provider.realm].checkRequest(fore,path)
except AuthRequiredExc,ae:
if self.request_version != 'HTTP/1.1':
self.log_error("Cannot require auth at %s",self.request_version)
self.send_error(401)
return
self._get_ignore_body(fore) # consume any body that came, not loose sync with input
self.send_response(401,'Authorization required')
self.send_header('WWW-Authenticate','%s realm="%s"' % (ae.atype,ae.realm))
self.send_header('Connection', 'keep-alive')
self.send_header('Content-Type','text/html')
self.send_header('Content-Length',len(self.auth_required_msg))
self.end_headers()
self.wfile.write(self.auth_required_msg)
return
except AuthRejectedExc,e:
self.log_error("Rejected auth: %s" % e.args[0])
self.send_error(401,e.args[0])
self.close_connection = 1
return
self.request_version = fore.request_version
if auth_provider and auth_provider.realm:
try:
self.sec_realms[auth_provider.realm].checkRequest(fore,path)
except AuthRequiredExc,ae:
if self.request_version != 'HTTP/1.1':
self.log_error("Cannot require auth at %s",self.request_version)
self.send_error(401)
return
self._get_ignore_body(fore) # consume any body that came, not loose sync with input
self.send_response(401,'Authorization required')
self.send_header('WWW-Authenticate','%s realm="%s"' % (ae.atype,ae.realm))
self.send_header('Connection', 'keep-alive')
self.send_header('Content-Type','text/html')
self.send_header('Content-Length',len(self.auth_required_msg))
self.end_headers()
self.wfile.write(self.auth_required_msg)
return
except AuthRejectedExc,e:
self.log_error("Rejected auth: %s" % e.args[0])
self.send_error(401,e.args[0])
self.close_connection = 1
return
mname = 'do_' + fore.command
if not hasattr(fore, mname):
fore.send_error(501, "Unsupported method (%r)" % fore.command)
return
fore.close_connection = 0
fore.close_connection = 0
method = getattr(fore, mname)
method()
if fore.close_connection:
# print "Closing connection because of handler"
self.close_connection = fore.close_connection
if fore.close_connection:
# print "Closing connection because of handler"
self.close_connection = fore.close_connection
def parse_rawline(self):
"""Parse a request (internal).
@ -295,67 +295,67 @@ class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
else:
self.send_error(400, "Bad request syntax (%r)" % requestline)
return False
self.request_version = version
self.command, self.path, self.version = command, path, version
return True
self.request_version = version
self.command, self.path, self.version = command, path, version
return True
def handle_one_request(self):
"""Handle a single HTTP request.
Dispatch to the correct handler.
Dispatch to the correct handler.
"""
self.request.setblocking(True)
self.request.setblocking(True)
self.raw_requestline = self.rfile.readline()
if not self.raw_requestline:
self.close_connection = 1
# self.log_message("no requestline, connection closed?")
return
if not self.parse_rawline():
self.log_message("Could not parse rawline.")
return
if not self.raw_requestline:
self.close_connection = 1
# self.log_message("no requestline, connection closed?")
return
if not self.parse_rawline():
self.log_message("Could not parse rawline.")
return
# self.parse_request(): # Do NOT parse here. the first line should be the only
for vdir in self.server.vdirs:
p = vdir.matches(self.path)
if p == False:
continue
npath = self.path[len(p):]
if not npath.startswith('/'):
npath = '/' + npath
for vdir in self.server.vdirs:
p = vdir.matches(self.path)
if p == False:
continue
npath = self.path[len(p):]
if not npath.startswith('/'):
npath = '/' + npath
if not self.in_handlers.has_key(p):
self.in_handlers[p] = vdir.handler(noconnection(),self.client_address,self.server)
if vdir.auth_provider:
vdir.auth_provider.setupAuth(self, self.in_handlers[p])
hnd = self.in_handlers[p]
hnd.rfile = self.rfile
hnd.wfile = self.wfile
self.rlpath = self.raw_requestline
self._handle_one_foreign(hnd,npath, vdir.auth_provider)
# print "Handled, closing = ", self.close_connection
return
# if no match:
if not self.in_handlers.has_key(p):
self.in_handlers[p] = vdir.handler(noconnection(),self.client_address,self.server)
if vdir.auth_provider:
vdir.auth_provider.setupAuth(self, self.in_handlers[p])
hnd = self.in_handlers[p]
hnd.rfile = self.rfile
hnd.wfile = self.wfile
self.rlpath = self.raw_requestline
self._handle_one_foreign(hnd,npath, vdir.auth_provider)
# print "Handled, closing = ", self.close_connection
return
# if no match:
self.send_error(404, "Path not found: %s" % self.path)
return
def _get_ignore_body(self,fore):
if not fore.headers.has_key("content-length"):
return
max_chunk_size = 10*1024*1024
size_remaining = int(fore.headers["content-length"])
got = ''
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
got = fore.rfile.read(chunk_size)
size_remaining -= len(got)
if not fore.headers.has_key("content-length"):
return
max_chunk_size = 10*1024*1024
size_remaining = int(fore.headers["content-length"])
got = ''
while size_remaining:
chunk_size = min(size_remaining, max_chunk_size)
got = fore.rfile.read(chunk_size)
size_remaining -= len(got)
class SecureMultiHTTPHandler(MultiHTTPHandler):
def getcert_fnames(self):
""" Return a pair with the filenames of ssl cert,key
Override this to direct to other filenames
"""
return ('server.cert','server.key')
""" Return a pair with the filenames of ssl cert,key
Override this to direct to other filenames
"""
return ('server.cert','server.key')
def setup(self):
import ssl
certfile, keyfile = self.getcert_fnames()
@ -386,10 +386,10 @@ import threading
class ConnThreadingMixIn:
"""Mix-in class to handle each _connection_ in a new thread.
This is necessary for persistent connections, where multiple
requests should be handled synchronously at each connection, but
multiple connections can run in parallel.
"""
This is necessary for persistent connections, where multiple
requests should be handled synchronously at each connection, but
multiple connections can run in parallel.
"""
# Decides how threads will act upon termination of the
# main process
@ -401,7 +401,7 @@ class ConnThreadingMixIn:
if self.daemon_threads:
t.setDaemon (1)
t.start()
def _handle_request2(self):
"""Handle one request, without blocking.

View File

@ -119,14 +119,14 @@ class Cursor(object):
try:
params = params or None
res = self._obj.execute(query, params)
except psycopg2.ProgrammingError, pe:
logger= netsvc.Logger()
logger.notifyChannel('sql_db', netsvc.LOG_ERROR, "Programming error: %s, in query %s" % (pe, query))
raise
except psycopg2.ProgrammingError, pe:
logger= netsvc.Logger()
logger.notifyChannel('sql_db', netsvc.LOG_ERROR, "Programming error: %s, in query %s" % (pe, query))
raise
except Exception, e:
log("bad query: %s" % self._obj.query)
log(e)
raise
raise
if self.sql_log:
log("query: %s" % self._obj.query)
@ -144,8 +144,8 @@ class Cursor(object):
return res
def print_log(self):
global sql_counter
sql_counter += self.count
global sql_counter
sql_counter += self.count
def process(type):
sqllogs = {'from':self.sql_from_log, 'into':self.sql_into_log}
sum = 0

View File

@ -66,7 +66,7 @@ class configmanager(object):
'import_partial': "",
'pidfile': None,
'logfile': None,
'logrotate': '1',
'logrotate': '1',
'smtp_server': 'localhost',
'smtp_user': False,
'smtp_port':25,
@ -82,8 +82,8 @@ class configmanager(object):
'login_message': False,
'list_db' : True,
}
self.misc = {}
self.misc = {}
hasSSL = check_ssl()
@ -135,7 +135,7 @@ class configmanager(object):
group = optparse.OptionGroup(parser, "Logging Configuration")
group.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
group.add_option("--no-logrotate", dest="logrotate", action="store_false",
default=None, help="do not rotate the logfile")
default=None, help="do not rotate the logfile")
group.add_option("--syslog", action="store_true", dest="syslog",
default=False, help="Send the log to the syslog server")
group.add_option('--log-level', dest='log_level', type='choice', choices=self._LOGLEVELS.keys(),
@ -226,7 +226,7 @@ class configmanager(object):
'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
'netrpc', 'xmlrpc', 'syslog', 'without_demo']
'netrpc', 'xmlrpc', 'syslog', 'without_demo']
if hasSSL:
keys.extend(['smtp_ssl', 'secure_cert_file', 'secure_pkey_file'])
@ -341,18 +341,18 @@ class configmanager(object):
if value=='False' or value=='false':
value = False
self.options[name] = value
#parse the other sections, as well
for sec in p.sections():
if sec == 'options':
continue
if not self.misc.has_key(sec):
self.misc[sec]= {}
for (name, value) in p.items(sec):
if value=='True' or value=='true':
value = True
if value=='False' or value=='false':
value = False
self.misc[sec][name] = value
#parse the other sections, as well
for sec in p.sections():
if sec == 'options':
continue
if not self.misc.has_key(sec):
self.misc[sec]= {}
for (name, value) in p.items(sec):
if value=='True' or value=='true':
value = True
if value=='False' or value=='false':
value = False
self.misc[sec][name] = value
except IOError:
pass
except ConfigParser.NoSectionError:
@ -369,10 +369,10 @@ class configmanager(object):
p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt]))
else:
p.set('options', opt, self.options[opt])
for sec in self.misc.keys():
for opt in self.misc[sec].keys():
p.set(sec,opt,self.misc[sec][opt])
for sec in self.misc.keys():
for opt in self.misc[sec].keys():
p.set(sec,opt,self.misc[sec][opt])
# try to create the directories and write the file
try:

View File

@ -386,15 +386,15 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non
smtp_server = config['smtp_server']
if smtp_server.startswith('maildir:/'):
from mailbox import Maildir
maildir_path = smtp_server[8:]
try:
mdir = Maildir(maildir_path,factory=None, create = True)
mdir.add(msg.as_string(True))
return True
except Exception,e:
netsvc.Logger().notifyChannel('email_send (maildir)', netsvc.LOG_ERROR, e)
return False
maildir_path = smtp_server[8:]
try:
mdir = Maildir(maildir_path,factory=None, create = True)
mdir.add(msg.as_string(True))
return True
except Exception,e:
netsvc.Logger().notifyChannel('email_send (maildir)', netsvc.LOG_ERROR, e)
return False
try:
oldstderr = smtplib.stderr
s = smtplib.SMTP()

View File

@ -29,38 +29,38 @@ __export_bis = {}
import sys
def __init_ebis():
global __export_bis
_evars = [ 'abs', 'all', 'any', 'basestring' , 'bool',
'chr', 'cmp','complex', 'dict', 'divmod', 'enumerate',
'float', 'frozenset', 'getattr', 'hasattr', 'hash',
'hex', 'id','int', 'iter', 'len', 'list', 'long', 'map', 'max',
'min', 'oct', 'ord','pow', 'range', 'reduce', 'repr',
'reversed', 'round', 'set', 'setattr', 'slice','sorted', 'str',
'sum', 'tuple','type', 'unichr','unicode', 'xrange',
'True','False', 'None', 'NotImplemented', 'Ellipsis', ]
if sys.version_info[0:2] >= (2,6):
_evars.extend(['bin', 'format', 'next'])
for v in _evars:
__export_bis[v] = __builtins__[v]
global __export_bis
_evars = [ 'abs', 'all', 'any', 'basestring' , 'bool',
'chr', 'cmp','complex', 'dict', 'divmod', 'enumerate',
'float', 'frozenset', 'getattr', 'hasattr', 'hash',
'hex', 'id','int', 'iter', 'len', 'list', 'long', 'map', 'max',
'min', 'oct', 'ord','pow', 'range', 'reduce', 'repr',
'reversed', 'round', 'set', 'setattr', 'slice','sorted', 'str',
'sum', 'tuple','type', 'unichr','unicode', 'xrange',
'True','False', 'None', 'NotImplemented', 'Ellipsis', ]
if sys.version_info[0:2] >= (2,6):
_evars.extend(['bin', 'format', 'next'])
for v in _evars:
__export_bis[v] = __builtins__[v]
__init_ebis()
def safe_eval(expr,sglobals,slocals = None):
""" A little safer version of eval().
This one, will use fewer builtin functions, so that only
arithmetic and logic expressions can really work """
global __export_bis
""" A little safer version of eval().
This one, will use fewer builtin functions, so that only
arithmetic and logic expressions can really work """
global __export_bis
if not sglobals.has_key('__builtins__'):
# we copy, because we wouldn't want successive calls to safe_eval
# to be able to alter the builtins.
sglobals['__builtins__'] = __export_bis.copy()
return eval(expr,sglobals,slocals)
#eof
if not sglobals.has_key('__builtins__'):
# we copy, because we wouldn't want successive calls to safe_eval
# to be able to alter the builtins.
sglobals['__builtins__'] = __export_bis.copy()
return eval(expr,sglobals,slocals)
#eof

View File

@ -133,12 +133,12 @@ class GettextAlias(object):
return source
cr = frame.f_locals.get('cr')
try:
lang = (frame.f_locals.get('context') or {}).get('lang', False)
if not (lang and cr):
return source
except:
return source
try:
lang = (frame.f_locals.get('context') or {}).get('lang', False)
if not (lang and cr):
return source
except:
return source
cr.execute('select value from ir_translation where lang=%s and type=%s and src=%s', (lang, 'code', source))
res_trans = cr.fetchone()
@ -154,7 +154,7 @@ class TinyPoFile(object):
def __iter__(self):
self.buffer.seek(0)
self.lines = self._get_lines()
self.lines_count = len(self.lines);
self.lines_count = len(self.lines);
self.first = True
self.tnrs= []
@ -170,7 +170,7 @@ class TinyPoFile(object):
return lines
def cur_line(self):
return (self.lines_count - len(self.lines))
return (self.lines_count - len(self.lines))
def next(self):
def unquote(str):
@ -185,30 +185,30 @@ class TinyPoFile(object):
else:
tmp_tnrs = []
line = None
fuzzy = False
fuzzy = False
while (not line):
if 0 == len(self.lines):
raise StopIteration()
line = self.lines.pop(0).strip()
if line.startswith('#:'):
if ' ' in line[2:].strip():
for lpart in line[2:].strip().split(' '):
tmp_tnrs.append(lpart.strip().split(':',2))
else:
if ' ' in line[2:].strip():
for lpart in line[2:].strip().split(' '):
tmp_tnrs.append(lpart.strip().split(':',2))
else:
tmp_tnrs.append( line[2:].strip().split(':',2) )
elif line.startswith('#,') and (line[2:].strip() == 'fuzzy'):
fuzzy = True
elif line.startswith('#,') and (line[2:].strip() == 'fuzzy'):
fuzzy = True
line = self.lines.pop(0).strip()
while not line:
# allow empty lines between comments and msgid
line = self.lines.pop(0).strip()
if line.startswith('#~ '):
while line.startswith('#~ ') or not line.strip():
if 0 == len(self.lines):
if line.startswith('#~ '):
while line.startswith('#~ ') or not line.strip():
if 0 == len(self.lines):
raise StopIteration()
line = self.lines.pop(0)
# This has been a deprecated entry, don't return anything
return self.next()
line = self.lines.pop(0)
# This has been a deprecated entry, don't return anything
return self.next()
if not line.startswith('msgid'):
@ -242,9 +242,9 @@ class TinyPoFile(object):
self.tnrs.append((t, n, r, source, trad))
self.first = False
if name == None:
return self.next()
if name == None:
return self.next()
return type, name, res_id, source, trad
def write_infos(self, modules):
@ -279,7 +279,7 @@ class TinyPoFile(object):
def quote(s):
return '"%s"' % s.replace('"','\\"') \
.replace('\n', '\\n"\n"') \
.replace(' \\ ',' \\\\ ')
.replace(' \\ ',' \\\\ ')
plurial = len(modules) > 1 and 's' or ''
@ -490,9 +490,9 @@ def trans_generate(lang, modules, dbname=None):
}
# export fields
if not result.has_key('fields'):
logger.notifyChannel("db",netsvc.LOG_WARNING,"res has no fields: %r" % result)
continue
if not result.has_key('fields'):
logger.notifyChannel("db",netsvc.LOG_WARNING,"res has no fields: %r" % result)
continue
for field_name, field_def in result['fields'].iteritems():
res_name = name + ',' + field_name
@ -517,11 +517,11 @@ def trans_generate(lang, modules, dbname=None):
push_translation(module, 'wizard_button', res_name, 0, button_label)
elif model=='ir.model.fields':
try:
try:
field_name = encode(obj.name)
except AttributeError, exc:
logger.notifyChannel("db", netsvc.LOG_ERROR, "name error in %s: %s" % (xml_name,str(exc)))
continue
except AttributeError, exc:
logger.notifyChannel("db", netsvc.LOG_ERROR, "name error in %s: %s" % (xml_name,str(exc)))
continue
objmodel = pool.get(obj.model)
if not objmodel or not field_name in objmodel._columns:
continue
@ -578,28 +578,28 @@ def trans_generate(lang, modules, dbname=None):
for field_name,field_def in pool.get(model)._columns.items():
if field_def.translate:
name = model + "," + field_name
try:
try:
trad = getattr(obj, field_name) or ''
except:
trad = ''
except:
trad = ''
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):
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]
return 'base' # files that are not in a module are considered as being in 'base' module
@ -760,8 +760,8 @@ def trans_load_data(db_name, fileobj, fileformat, lang, strict=False, lang_name=
# if the resource id (res_id) is in that list, use it,
# otherwise use the whole list
if not ids:
ids = []
if not ids:
ids = []
ids = (dic['res_id'] in ids) and [dic['res_id']] or ids
for id in ids:
dic['res_id'] = id