[FIX] replaced <TAB> with four white space.
bzr revid: hmo@tinyerp.com-20091124144405-9mzd91chohvf0uu7
This commit is contained in:
parent
dda5ed6bb1
commit
d8ce3f1e2a
|
@ -52,10 +52,10 @@ sys.path.insert(1, _ad)
|
||||||
ad_cnt=1
|
ad_cnt=1
|
||||||
for adp in ad_paths:
|
for adp in ad_paths:
|
||||||
if adp != _ad:
|
if adp != _ad:
|
||||||
sys.path.insert(ad_cnt, adp)
|
sys.path.insert(ad_cnt, adp)
|
||||||
ad_cnt+=1
|
ad_cnt+=1
|
||||||
|
|
||||||
ad_paths.append(_ad) # for get_module_path
|
ad_paths.append(_ad) # for get_module_path
|
||||||
|
|
||||||
# Modules already loaded
|
# Modules already loaded
|
||||||
loaded = []
|
loaded = []
|
||||||
|
@ -289,7 +289,7 @@ def get_modules():
|
||||||
|
|
||||||
plist = []
|
plist = []
|
||||||
for ad in ad_paths:
|
for ad in ad_paths:
|
||||||
plist.extend(listdir(ad))
|
plist.extend(listdir(ad))
|
||||||
return list(set(plist))
|
return list(set(plist))
|
||||||
|
|
||||||
def get_modules_with_version():
|
def get_modules_with_version():
|
||||||
|
@ -318,7 +318,7 @@ def upgrade_graph(graph, cr, module_list, force=None):
|
||||||
mod_path = get_module_path(module)
|
mod_path = get_module_path(module)
|
||||||
terp_file = get_module_resource(module, '__terp__.py')
|
terp_file = get_module_resource(module, '__terp__.py')
|
||||||
if not mod_path or not terp_file:
|
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))
|
cr.execute("update ir_module_module set state=%s where name=%s", ('uninstallable', module))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
|
|
|
@ -47,15 +47,15 @@ class ir_sequence(osv.osv):
|
||||||
'number_next': fields.integer('Next Number', required=True),
|
'number_next': fields.integer('Next Number', required=True),
|
||||||
'number_increment': fields.integer('Increment Number', required=True),
|
'number_increment': fields.integer('Increment Number', required=True),
|
||||||
'padding' : fields.integer('Number padding', 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."),
|
'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.")
|
'weight': fields.integer('Weight',required=True, help="If two sequences match, the highest weight will be used.")
|
||||||
}
|
}
|
||||||
_defaults = {
|
_defaults = {
|
||||||
'active': lambda *a: True,
|
'active': lambda *a: True,
|
||||||
'number_increment': lambda *a: 1,
|
'number_increment': lambda *a: 1,
|
||||||
'number_next': lambda *a: 1,
|
'number_next': lambda *a: 1,
|
||||||
'padding' : lambda *a : 0,
|
'padding' : lambda *a : 0,
|
||||||
'weight' : lambda *a: 10,
|
'weight' : lambda *a: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _process(self, s):
|
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):
|
def get_id(self, cr, uid, sequence_id, test='id=%s', context=None):
|
||||||
if not context:
|
if not context:
|
||||||
context = {}
|
context = {}
|
||||||
try:
|
try:
|
||||||
cr.execute('SELECT id, number_next, prefix, suffix, padding, condition \
|
cr.execute('SELECT id, number_next, prefix, suffix, padding, condition \
|
||||||
FROM ir_sequence \
|
FROM ir_sequence \
|
||||||
WHERE '+test+' AND active=%s ORDER BY weight DESC, length(COALESCE(condition,\'\')) DESC \
|
WHERE '+test+' AND active=%s ORDER BY weight DESC, length(COALESCE(condition,\'\')) DESC \
|
||||||
FOR UPDATE', (sequence_id, True))
|
FOR UPDATE', (sequence_id, True))
|
||||||
for res in cr.dictfetchall():
|
for res in cr.dictfetchall():
|
||||||
if res['condition']:
|
if res['condition']:
|
||||||
print "ir_seq: %s has condition:" %res['id'], res['condition'],
|
print "ir_seq: %s has condition:" %res['id'], res['condition'],
|
||||||
try:
|
try:
|
||||||
bo = safe_eval(res['condition'],context)
|
bo = safe_eval(res['condition'],context)
|
||||||
if not bo:
|
if not bo:
|
||||||
print "not matched"
|
print "not matched"
|
||||||
continue
|
continue
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
# it would be normal to have exceptions, because
|
# it would be normal to have exceptions, because
|
||||||
# the domain may contain errors
|
# the domain may contain errors
|
||||||
print "Exception.\ne:",e
|
print "Exception.\ne:",e
|
||||||
print "Context:", context
|
print "Context:", context
|
||||||
continue
|
continue
|
||||||
print "Matched!"
|
print "Matched!"
|
||||||
|
|
||||||
cr.execute('UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s AND active=%s', (res['id'], True))
|
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']:
|
if res['number_next']:
|
||||||
|
|
|
@ -147,7 +147,7 @@ showpage'''
|
||||||
inst_id = inst_id[0]
|
inst_id = inst_id[0]
|
||||||
graph = pydot.Dot(fontsize='16', label="""\\\n\\nWorkflow: %s\\n OSV: %s""" % (wkfinfo['name'],wkfinfo['osv']),
|
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',
|
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))
|
graph_instance_get(cr, graph, inst_id, data.get('nested', False))
|
||||||
ps_string = graph.create(prog='dot', format='ps')
|
ps_string = graph.create(prog='dot', format='ps')
|
||||||
|
|
|
@ -29,37 +29,37 @@ class ir_module_reference_print(report_sxw.rml_parse):
|
||||||
'time': time,
|
'time': time,
|
||||||
'findobj': self._object_find,
|
'findobj': self._object_find,
|
||||||
'objdoc': self._object_doc,
|
'objdoc': self._object_doc,
|
||||||
'objdoc2': self._object_doc2,
|
'objdoc2': self._object_doc2,
|
||||||
'findflds': self._fields_find,
|
'findflds': self._fields_find,
|
||||||
})
|
})
|
||||||
def _object_doc(self, obj):
|
def _object_doc(self, obj):
|
||||||
modobj = self.pool.get(obj)
|
modobj = self.pool.get(obj)
|
||||||
strdocs= modobj.__doc__
|
strdocs= modobj.__doc__
|
||||||
if not strdocs:
|
if not strdocs:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
strdocs=strdocs.strip().splitlines(True)
|
strdocs=strdocs.strip().splitlines(True)
|
||||||
res = ''
|
res = ''
|
||||||
for stre in strdocs:
|
for stre in strdocs:
|
||||||
if not stre or stre.isspace():
|
if not stre or stre.isspace():
|
||||||
break
|
break
|
||||||
res += stre
|
res += stre
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _object_doc2(self, obj):
|
def _object_doc2(self, obj):
|
||||||
modobj = self.pool.get(obj)
|
modobj = self.pool.get(obj)
|
||||||
strdocs= modobj.__doc__
|
strdocs= modobj.__doc__
|
||||||
if not strdocs:
|
if not strdocs:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
strdocs=strdocs.strip().splitlines(True)
|
strdocs=strdocs.strip().splitlines(True)
|
||||||
res = []
|
res = []
|
||||||
fou = False
|
fou = False
|
||||||
for stre in strdocs:
|
for stre in strdocs:
|
||||||
if fou:
|
if fou:
|
||||||
res.append(stre.strip())
|
res.append(stre.strip())
|
||||||
elif not stre or stre.isspace():
|
elif not stre or stre.isspace():
|
||||||
fou = True
|
fou = True
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _object_find(self, module):
|
def _object_find(self, module):
|
||||||
|
|
|
@ -80,7 +80,7 @@ class wizard_export_lang(osv.osv_memory):
|
||||||
) ),
|
) ),
|
||||||
}
|
}
|
||||||
_defaults = { 'state': lambda *a: 'choose',
|
_defaults = { 'state': lambda *a: 'choose',
|
||||||
'name': lambda *a: 'lang.tar.gz'
|
'name': lambda *a: 'lang.tar.gz'
|
||||||
}
|
}
|
||||||
wizard_export_lang()
|
wizard_export_lang()
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,10 @@ class groups(osv.osv):
|
||||||
return gid
|
return gid
|
||||||
|
|
||||||
def copy(self, cr, uid, id, default={}, context={}, done_list=[], local=False):
|
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()
|
default = default.copy()
|
||||||
if not 'name' in default:
|
if not 'name' in default:
|
||||||
default['name'] = group['name']
|
default['name'] = group['name']
|
||||||
default['name'] = default['name'] + _(' (copy)')
|
default['name'] = default['name'] + _(' (copy)')
|
||||||
return super(groups, self).copy(cr, uid, id, default, context=context)
|
return super(groups, self).copy(cr, uid, id, default, context=context)
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ import release
|
||||||
class Service(object):
|
class Service(object):
|
||||||
""" Base class for *Local* services
|
""" Base class for *Local* services
|
||||||
|
|
||||||
Functionality here is trusted, no authentication.
|
Functionality here is trusted, no authentication.
|
||||||
"""
|
"""
|
||||||
_services = {}
|
_services = {}
|
||||||
def __init__(self, name, audience=''):
|
def __init__(self, name, audience=''):
|
||||||
|
@ -48,11 +48,11 @@ class Service(object):
|
||||||
self._methods = {}
|
self._methods = {}
|
||||||
|
|
||||||
def joinGroup(self, name):
|
def joinGroup(self, name):
|
||||||
raise Exception("No group for local services")
|
raise Exception("No group for local services")
|
||||||
#GROUPS.setdefault(name, {})[self.__name] = self
|
#GROUPS.setdefault(name, {})[self.__name] = self
|
||||||
|
|
||||||
def service_exist(self,name):
|
def service_exist(self,name):
|
||||||
return Service._services.has_key(name)
|
return Service._services.has_key(name)
|
||||||
|
|
||||||
def exportMethod(self, method):
|
def exportMethod(self, method):
|
||||||
if callable(method):
|
if callable(method):
|
||||||
|
@ -67,9 +67,9 @@ class Service(object):
|
||||||
class LocalService(object):
|
class LocalService(object):
|
||||||
""" Proxy for local services.
|
""" Proxy for local services.
|
||||||
|
|
||||||
Any instance of this class will behave like the single instance
|
Any instance of this class will behave like the single instance
|
||||||
of Service(name)
|
of Service(name)
|
||||||
"""
|
"""
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
self.__name = name
|
self.__name = name
|
||||||
try:
|
try:
|
||||||
|
@ -158,12 +158,12 @@ def init_logger():
|
||||||
dirname = os.path.dirname(logf)
|
dirname = os.path.dirname(logf)
|
||||||
if dirname and not os.path.isdir(dirname):
|
if dirname and not os.path.isdir(dirname):
|
||||||
os.makedirs(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)
|
handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30)
|
||||||
elif os.name == 'posix':
|
elif os.name == 'posix':
|
||||||
handler = logging.handlers.WatchedFileHandler(logf)
|
handler = logging.handlers.WatchedFileHandler(logf)
|
||||||
else:
|
else:
|
||||||
handler = logging.handlers.FileHandler(logf)
|
handler = logging.handlers.FileHandler(logf)
|
||||||
except Exception, ex:
|
except Exception, ex:
|
||||||
sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n")
|
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)
|
||||||
|
@ -223,27 +223,27 @@ class Logger(object):
|
||||||
if isinstance(msg, Exception):
|
if isinstance(msg, Exception):
|
||||||
msg = tools.exception_to_unicode(msg)
|
msg = tools.exception_to_unicode(msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
msg = tools.ustr(msg).strip()
|
msg = tools.ustr(msg).strip()
|
||||||
if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',True):
|
if level in (LOG_ERROR,LOG_CRITICAL) and tools.config.get_misc('debug','env_info',True):
|
||||||
msg = common().exp_get_server_environment() + "\n" + msg
|
msg = common().exp_get_server_environment() + "\n" + msg
|
||||||
|
|
||||||
result = msg.split('\n')
|
result = msg.split('\n')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
result = msg.strip().split('\n')
|
result = msg.strip().split('\n')
|
||||||
try:
|
try:
|
||||||
if len(result)>1:
|
if len(result)>1:
|
||||||
for idx, s in enumerate(result):
|
for idx, s in enumerate(result):
|
||||||
level_method('[%02d]: %s' % (idx+1, s,))
|
level_method('[%02d]: %s' % (idx+1, s,))
|
||||||
elif result:
|
elif result:
|
||||||
level_method(result[0])
|
level_method(result[0])
|
||||||
except IOError,e:
|
except IOError,e:
|
||||||
# TODO: perhaps reset the logger streams?
|
# TODO: perhaps reset the logger streams?
|
||||||
#if logrotate closes our files, we end up here..
|
#if logrotate closes our files, we end up here..
|
||||||
pass
|
pass
|
||||||
except:
|
except:
|
||||||
# better ignore the exception and carry on..
|
# better ignore the exception and carry on..
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def set_loglevel(self, level):
|
def set_loglevel(self, level):
|
||||||
log = logging.getLogger()
|
log = logging.getLogger()
|
||||||
|
@ -364,10 +364,10 @@ class OpenERPDispatcher:
|
||||||
self.log('service', service_name)
|
self.log('service', service_name)
|
||||||
self.log('method', method)
|
self.log('method', method)
|
||||||
self.log('params', params)
|
self.log('params', params)
|
||||||
if hasattr(self,'auth_provider'):
|
if hasattr(self,'auth_provider'):
|
||||||
auth = self.auth_provider
|
auth = self.auth_provider
|
||||||
else:
|
else:
|
||||||
auth = None
|
auth = None
|
||||||
result = ExportService.getService(service_name).dispatch(method, auth, params)
|
result = ExportService.getService(service_name).dispatch(method, auth, params)
|
||||||
self.log('result', result)
|
self.log('result', result)
|
||||||
# We shouldn't marshall None,
|
# We shouldn't marshall None,
|
||||||
|
|
|
@ -56,8 +56,8 @@ __version__ = release.version
|
||||||
# We DON't log this using the standard logger, because we might mess
|
# We DON't log this using the standard logger, because we might mess
|
||||||
# with the logfile's permissions. Just do a quick exit here.
|
# with the logfile's permissions. Just do a quick exit here.
|
||||||
if pwd.getpwuid(os.getuid())[0] == 'root' :
|
if pwd.getpwuid(os.getuid())[0] == 'root' :
|
||||||
sys.stderr.write("Attempted to run OpenERP server as root. This is not good, aborting.\n")
|
sys.stderr.write("Attempted to run OpenERP server as root. This is not good, aborting.\n")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
#----------------------------------------------------------
|
#----------------------------------------------------------
|
||||||
# get logger
|
# get logger
|
||||||
|
@ -114,13 +114,13 @@ import addons
|
||||||
import service.http_server
|
import service.http_server
|
||||||
|
|
||||||
if not ( tools.config["stop_after_init"] or \
|
if not ( tools.config["stop_after_init"] or \
|
||||||
tools.config["translate_in"] or \
|
tools.config["translate_in"] or \
|
||||||
tools.config["translate_out"] ):
|
tools.config["translate_out"] ):
|
||||||
service.http_server.init_servers()
|
service.http_server.init_servers()
|
||||||
service.http_server.init_xmlrpc()
|
service.http_server.init_xmlrpc()
|
||||||
|
|
||||||
import service.netrpc_server
|
import service.netrpc_server
|
||||||
service.netrpc_server.init_servers()
|
service.netrpc_server.init_servers()
|
||||||
|
|
||||||
if tools.config['db_name']:
|
if tools.config['db_name']:
|
||||||
for db in tools.config['db_name'].split(','):
|
for db in tools.config['db_name'].split(','):
|
||||||
|
|
|
@ -585,14 +585,14 @@ class many2many(_column):
|
||||||
|
|
||||||
|
|
||||||
def get_nice_size(a):
|
def get_nice_size(a):
|
||||||
(x,y) = a
|
(x,y) = a
|
||||||
if isinstance(y, (int,long)):
|
if isinstance(y, (int,long)):
|
||||||
size = y
|
size = y
|
||||||
elif y:
|
elif y:
|
||||||
y = len(y)
|
y = len(y)
|
||||||
else:
|
else:
|
||||||
y = 0
|
y = 0
|
||||||
return (x, tools.human_size(size))
|
return (x, tools.human_size(size))
|
||||||
|
|
||||||
# ---------------------------------------------------------
|
# ---------------------------------------------------------
|
||||||
# Function fields
|
# Function fields
|
||||||
|
|
|
@ -205,9 +205,9 @@ class browse_record(object):
|
||||||
d[n].set_value(self._cr, self._uid, d[n], self, f, lang_obj)
|
d[n].set_value(self._cr, self._uid, d[n], self, f, lang_obj)
|
||||||
|
|
||||||
|
|
||||||
if not datas:
|
if not datas:
|
||||||
# Where did those ids come from? Perhaps old entries in ir_model_data?
|
# 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)))
|
raise except_orm('NoDataError', 'Field %s in %s%s'%(name,self._table_name,str(ids)))
|
||||||
# create browse records for 'remote' objects
|
# create browse records for 'remote' objects
|
||||||
for data in datas:
|
for data in datas:
|
||||||
for n, f in ffields:
|
for n, f in ffields:
|
||||||
|
@ -228,12 +228,12 @@ class browse_record(object):
|
||||||
elif f._type in ('one2many', 'many2many') and len(data[n]):
|
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)
|
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)
|
self._data[data['id']].update(data)
|
||||||
if not name in self._data[self._id]:
|
if not name in self._data[self._id]:
|
||||||
#how did this happen?
|
#how did this happen?
|
||||||
logger = netsvc.Logger()
|
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,"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)))
|
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))
|
raise AttributeError(_('Unknown attribute %s in %s ') % (str(name),self._table_name))
|
||||||
return self._data[self._id][name]
|
return self._data[self._id][name]
|
||||||
|
|
||||||
def __getattr__(self, name):
|
def __getattr__(self, name):
|
||||||
|
@ -671,10 +671,10 @@ class orm_template(object):
|
||||||
else:
|
else:
|
||||||
module, xml_id = current_module, line[i]
|
module, xml_id = current_module, line[i]
|
||||||
id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
|
id = ir_model_data_obj._get_id(cr, uid, module, xml_id)
|
||||||
res_res_id = ir_model_data_obj.read(cr, uid, [id],
|
res_res_id = ir_model_data_obj.read(cr, uid, [id],
|
||||||
['res_id'])
|
['res_id'])
|
||||||
if res_res_id:
|
if res_res_id:
|
||||||
res_id = res_res_id[0]['res_id']
|
res_id = res_res_id[0]['res_id']
|
||||||
row[field[-1][:-3]] = res_id or False
|
row[field[-1][:-3]] = res_id or False
|
||||||
continue
|
continue
|
||||||
if (len(field) == len(prefix)+1) and \
|
if (len(field) == len(prefix)+1) and \
|
||||||
|
@ -962,7 +962,7 @@ class orm_template(object):
|
||||||
and getattr(self._columns[f], arg):
|
and getattr(self._columns[f], arg):
|
||||||
res[f][arg] = 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')
|
res_trans = translation_obj._get_source(cr, user, self._name + ',' + f, 'field', context.get('lang', False) or 'en_US')
|
||||||
if res_trans:
|
if res_trans:
|
||||||
res[f]['string'] = res_trans
|
res[f]['string'] = res_trans
|
||||||
|
@ -1373,7 +1373,7 @@ class orm_template(object):
|
||||||
result['name'] = 'default'
|
result['name'] = 'default'
|
||||||
result['field_parent'] = False
|
result['field_parent'] = False
|
||||||
result['view_id'] = 0
|
result['view_id'] = 0
|
||||||
|
|
||||||
xarch, xfields = self.__view_look_dom_arch(cr, user, result['arch'], view_id, context=context)
|
xarch, xfields = self.__view_look_dom_arch(cr, user, result['arch'], view_id, context=context)
|
||||||
result['arch'] = xarch
|
result['arch'] = xarch
|
||||||
result['fields'] = xfields
|
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)
|
self.pool.get('ir.model.access').check(cr, uid, 'ir.translation', 'read', context=context)
|
||||||
if not fields:
|
if not fields:
|
||||||
fields = self._columns.keys() + self._inherit_fields.keys()
|
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:
|
for lang in langs:
|
||||||
res[lang] = {'code': lang}
|
res[lang] = {'code': lang}
|
||||||
for f in fields:
|
for f in fields:
|
||||||
|
@ -1476,7 +1476,7 @@ class orm_template(object):
|
||||||
|
|
||||||
def write_string(self, cr, uid, id, langs, vals, context=None):
|
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)
|
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 lang in langs:
|
||||||
for field in vals:
|
for field in vals:
|
||||||
if field in self._columns:
|
if field in self._columns:
|
||||||
|
@ -1897,20 +1897,20 @@ class orm(orm_template):
|
||||||
"AND c.oid=a.attrelid " \
|
"AND c.oid=a.attrelid " \
|
||||||
"AND a.atttypid=t.oid", (self._table, k))
|
"AND a.atttypid=t.oid", (self._table, k))
|
||||||
res = cr.dictfetchall()
|
res = cr.dictfetchall()
|
||||||
if not res and hasattr(f,'oldname'):
|
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 " \
|
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 " \
|
"FROM pg_class c,pg_attribute a,pg_type t " \
|
||||||
"WHERE c.relname=%s " \
|
"WHERE c.relname=%s " \
|
||||||
"AND a.attname=%s " \
|
"AND a.attname=%s " \
|
||||||
"AND c.oid=a.attrelid " \
|
"AND c.oid=a.attrelid " \
|
||||||
"AND a.atttypid=t.oid", (self._table, f.oldname))
|
"AND a.atttypid=t.oid", (self._table, f.oldname))
|
||||||
res_old = cr.dictfetchall()
|
res_old = cr.dictfetchall()
|
||||||
logger.notifyChannel('orm', netsvc.LOG_DEBUG, 'trying to rename %s(%s) to %s'% (self._table, f.oldname, k))
|
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:
|
if res_old and len(res_old)==1:
|
||||||
cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % ( self._table,f.oldname, k))
|
cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % ( self._table,f.oldname, k))
|
||||||
res = res_old
|
res = res_old
|
||||||
res[0]['attname'] = k
|
res[0]['attname'] = k
|
||||||
|
|
||||||
if not res:
|
if not res:
|
||||||
if not isinstance(f, fields.function) or f.store:
|
if not isinstance(f, fields.function) or f.store:
|
||||||
|
|
||||||
|
@ -2342,7 +2342,7 @@ class orm(orm_template):
|
||||||
continue
|
continue
|
||||||
if self._columns[f].translate:
|
if self._columns[f].translate:
|
||||||
ids = map(lambda x: x['id'], res)
|
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)
|
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:
|
for r in res:
|
||||||
r[f] = res_trans.get(r['id'], False) or r[f]
|
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)
|
'where id in ('+ids_str+')', upd1)
|
||||||
|
|
||||||
if totranslate:
|
if totranslate:
|
||||||
# TODO: optimize
|
# TODO: optimize
|
||||||
for f in direct:
|
for f in direct:
|
||||||
if self._columns[f].translate:
|
if self._columns[f].translate:
|
||||||
src_trans = self.pool.get(self._name).read(cr,user,ids,[f])
|
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])]
|
data[f] = [(6, 0, data[f])]
|
||||||
|
|
||||||
trans_obj = self.pool.get('ir.translation')
|
trans_obj = self.pool.get('ir.translation')
|
||||||
#TODO: optimize translations
|
#TODO: optimize translations
|
||||||
trans_name=''
|
trans_name=''
|
||||||
for f in fields:
|
for f in fields:
|
||||||
trans_flag=True
|
trans_flag=True
|
||||||
|
|
|
@ -80,7 +80,7 @@ class report_rml(report_int):
|
||||||
'html': self.create_html,
|
'html': self.create_html,
|
||||||
'raw': self.create_raw,
|
'raw': self.create_raw,
|
||||||
'sxw': self.create_sxw,
|
'sxw': self.create_sxw,
|
||||||
'txt': self.create_txt,
|
'txt': self.create_txt,
|
||||||
'odt': self.create_odt,
|
'odt': self.create_odt,
|
||||||
'html2html' : self.create_html2html,
|
'html2html' : self.create_html2html,
|
||||||
'makohtml2html' :self.create_makohtml2html,
|
'makohtml2html' :self.create_makohtml2html,
|
||||||
|
|
|
@ -22,28 +22,28 @@
|
||||||
|
|
||||||
|
|
||||||
CustomTTFonts = [ ('Helvetica',"DejaVu Sans", "DejaVuSans.ttf", 'normal'),
|
CustomTTFonts = [ ('Helvetica',"DejaVu Sans", "DejaVuSans.ttf", 'normal'),
|
||||||
('Helvetica',"DejaVu Sans Bold", "DejaVuSans-Bold.ttf", 'bold'),
|
('Helvetica',"DejaVu Sans Bold", "DejaVuSans-Bold.ttf", 'bold'),
|
||||||
('Helvetica',"DejaVu Sans Oblique", "DejaVuSans-Oblique.ttf", 'italic'),
|
('Helvetica',"DejaVu Sans Oblique", "DejaVuSans-Oblique.ttf", 'italic'),
|
||||||
('Helvetica',"DejaVu Sans BoldOblique", "DejaVuSans-BoldOblique.ttf", 'bolditalic'),
|
('Helvetica',"DejaVu Sans BoldOblique", "DejaVuSans-BoldOblique.ttf", 'bolditalic'),
|
||||||
('Times',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
|
('Times',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
|
||||||
('Times',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
|
('Times',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
|
||||||
('Times',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
|
('Times',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
|
||||||
('Times',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
|
('Times',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
|
||||||
('Times-Roman',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
|
('Times-Roman',"Liberation Serif", "LiberationSerif-Regular.ttf", 'normal'),
|
||||||
('Times-Roman',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
|
('Times-Roman',"Liberation Serif Bold", "LiberationSerif-Bold.ttf", 'bold'),
|
||||||
('Times-Roman',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
|
('Times-Roman',"Liberation Serif Italic", "LiberationSerif-Italic.ttf", 'italic'),
|
||||||
('Times-Roman',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
|
('Times-Roman',"Liberation Serif BoldItalic", "LiberationSerif-BoldItalic.ttf", 'bolditalic'),
|
||||||
('ZapfDingbats',"DejaVu Serif", "DejaVuSerif.ttf", 'normal'),
|
('ZapfDingbats',"DejaVu Serif", "DejaVuSerif.ttf", 'normal'),
|
||||||
('ZapfDingbats',"DejaVu Serif Bold", "DejaVuSerif-Bold.ttf", 'bold'),
|
('ZapfDingbats',"DejaVu Serif Bold", "DejaVuSerif-Bold.ttf", 'bold'),
|
||||||
('ZapfDingbats',"DejaVu Serif Italic", "DejaVuSerif-Italic.ttf", 'italic'),
|
('ZapfDingbats',"DejaVu Serif Italic", "DejaVuSerif-Italic.ttf", 'italic'),
|
||||||
('ZapfDingbats',"DejaVu Serif BoldItalic", "DejaVuSerif-BoldItalic.ttf", 'bolditalic'),
|
('ZapfDingbats',"DejaVu Serif BoldItalic", "DejaVuSerif-BoldItalic.ttf", 'bolditalic'),
|
||||||
('Courier',"FreeMono", "FreeMono.ttf", 'normal'),
|
('Courier',"FreeMono", "FreeMono.ttf", 'normal'),
|
||||||
('Courier',"FreeMono Bold", "FreeMonoBold.ttf", 'bold'),
|
('Courier',"FreeMono Bold", "FreeMonoBold.ttf", 'bold'),
|
||||||
('Courier',"FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'),
|
('Courier',"FreeMono Oblique", "FreeMonoOblique.ttf", 'italic'),
|
||||||
('Courier',"FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'),]
|
('Courier',"FreeMono BoldOblique", "FreeMonoBoldOblique.ttf", 'bolditalic'),]
|
||||||
|
|
||||||
def SetCustomFonts(rmldoc):
|
def SetCustomFonts(rmldoc):
|
||||||
for name, font, fname, mode in CustomTTFonts:
|
for name, font, fname, mode in CustomTTFonts:
|
||||||
rmldoc.setTTFontMapping(name, font,fname, mode)
|
rmldoc.setTTFontMapping(name, font,fname, mode)
|
||||||
|
|
||||||
#eof
|
#eof
|
||||||
|
|
|
@ -167,21 +167,21 @@ class _rml_doc(object):
|
||||||
from reportlab.lib.fonts import addMapping
|
from reportlab.lib.fonts import addMapping
|
||||||
from reportlab.pdfbase import pdfmetrics
|
from reportlab.pdfbase import pdfmetrics
|
||||||
from reportlab.pdfbase.ttfonts import TTFont
|
from reportlab.pdfbase.ttfonts import TTFont
|
||||||
|
|
||||||
pdfmetrics.registerFont(TTFont(fontname, filename ))
|
pdfmetrics.registerFont(TTFont(fontname, filename ))
|
||||||
if (mode == 'all'):
|
if (mode == 'all'):
|
||||||
addMapping(face, 0, 0, fontname) #normal
|
addMapping(face, 0, 0, fontname) #normal
|
||||||
addMapping(face, 0, 1, fontname) #italic
|
addMapping(face, 0, 1, fontname) #italic
|
||||||
addMapping(face, 1, 0, fontname) #bold
|
addMapping(face, 1, 0, fontname) #bold
|
||||||
addMapping(face, 1, 1, fontname) #italic and bold
|
addMapping(face, 1, 1, fontname) #italic and bold
|
||||||
elif (mode== 'normal') or (mode == 'regular'):
|
elif (mode== 'normal') or (mode == 'regular'):
|
||||||
addMapping(face, 0, 0, fontname) #normal
|
addMapping(face, 0, 0, fontname) #normal
|
||||||
elif (mode == 'italic'):
|
elif (mode == 'italic'):
|
||||||
addMapping(face, 0, 1, fontname) #italic
|
addMapping(face, 0, 1, fontname) #italic
|
||||||
elif (mode == 'bold'):
|
elif (mode == 'bold'):
|
||||||
addMapping(face, 1, 0, fontname) #bold
|
addMapping(face, 1, 0, fontname) #bold
|
||||||
elif (mode == 'bolditalic'):
|
elif (mode == 'bolditalic'):
|
||||||
addMapping(face, 1, 1, fontname) #italic and bold
|
addMapping(face, 1, 1, fontname) #italic and bold
|
||||||
|
|
||||||
def _textual_image(self, node):
|
def _textual_image(self, node):
|
||||||
rc = ''
|
rc = ''
|
||||||
|
@ -797,10 +797,10 @@ def parseNode(rml, localcontext = {},fout=None, images={}, path='.',title=None):
|
||||||
r = _rml_doc(node, localcontext, images, path, title=title)
|
r = _rml_doc(node, localcontext, images, path, title=title)
|
||||||
#try to override some font mappings
|
#try to override some font mappings
|
||||||
try:
|
try:
|
||||||
from customfonts import SetCustomFonts
|
from customfonts import SetCustomFonts
|
||||||
SetCustomFonts(r)
|
SetCustomFonts(r)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
fp = cStringIO.StringIO()
|
fp = cStringIO.StringIO()
|
||||||
r.render(fp)
|
r.render(fp)
|
||||||
return fp.getvalue()
|
return fp.getvalue()
|
||||||
|
@ -811,10 +811,10 @@ def parseString(rml, localcontext = {},fout=None, images={}, path='.',title=None
|
||||||
|
|
||||||
#try to override some font mappings
|
#try to override some font mappings
|
||||||
try:
|
try:
|
||||||
from customfonts import SetCustomFonts
|
from customfonts import SetCustomFonts
|
||||||
SetCustomFonts(r)
|
SetCustomFonts(r)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if fout:
|
if fout:
|
||||||
fp = file(fout,'wb')
|
fp = file(fout,'wb')
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- 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
|
# Copyright (C) 2004-2008 Tiny SPRL (<http://tiny.be>). All Rights Reserved
|
||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
|
@ -49,93 +49,93 @@ import utils
|
||||||
Font_size= 10.0
|
Font_size= 10.0
|
||||||
|
|
||||||
def verbose(text):
|
def verbose(text):
|
||||||
sys.stderr.write(text+"\n");
|
sys.stderr.write(text+"\n");
|
||||||
|
|
||||||
class textbox():
|
class textbox():
|
||||||
"""A box containing plain text.
|
"""A box containing plain text.
|
||||||
It can have an offset, in chars.
|
It can have an offset, in chars.
|
||||||
Lines can be either text strings, or textbox'es, recursively.
|
Lines can be either text strings, or textbox'es, recursively.
|
||||||
"""
|
"""
|
||||||
def __init__(self,x=0, y=0):
|
def __init__(self,x=0, y=0):
|
||||||
self.posx = x
|
self.posx = x
|
||||||
self.posy = y
|
self.posy = y
|
||||||
self.lines = []
|
self.lines = []
|
||||||
self.curline = ''
|
self.curline = ''
|
||||||
self.endspace = False
|
self.endspace = False
|
||||||
|
|
||||||
def newline(self):
|
def newline(self):
|
||||||
if isinstance(self.curline, textbox):
|
if isinstance(self.curline, textbox):
|
||||||
self.lines.extend(self.curline.renderlines())
|
self.lines.extend(self.curline.renderlines())
|
||||||
else:
|
else:
|
||||||
self.lines.append(self.curline)
|
self.lines.append(self.curline)
|
||||||
self.curline = ''
|
self.curline = ''
|
||||||
|
|
||||||
def fline(self):
|
def fline(self):
|
||||||
if isinstance(self.curline, textbox):
|
if isinstance(self.curline, textbox):
|
||||||
self.lines.extend(self.curline.renderlines())
|
self.lines.extend(self.curline.renderlines())
|
||||||
elif len(self.curline):
|
elif len(self.curline):
|
||||||
self.lines.append(self.curline)
|
self.lines.append(self.curline)
|
||||||
self.curline = ''
|
self.curline = ''
|
||||||
|
|
||||||
def appendtxt(self,txt):
|
def appendtxt(self,txt):
|
||||||
"""Append some text to the current line.
|
"""Append some text to the current line.
|
||||||
Mimic the HTML behaviour, where all whitespace evaluates to
|
Mimic the HTML behaviour, where all whitespace evaluates to
|
||||||
a single space """
|
a single space """
|
||||||
if not txt:
|
if not txt:
|
||||||
return
|
return
|
||||||
bs = es = False
|
bs = es = False
|
||||||
if txt[0].isspace():
|
if txt[0].isspace():
|
||||||
bs = True
|
bs = True
|
||||||
if txt[len(txt)-1].isspace():
|
if txt[len(txt)-1].isspace():
|
||||||
es = True
|
es = True
|
||||||
if bs and not self.endspace:
|
if bs and not self.endspace:
|
||||||
self.curline += " "
|
self.curline += " "
|
||||||
self.curline += txt.strip().replace("\n"," ").replace("\t"," ")
|
self.curline += txt.strip().replace("\n"," ").replace("\t"," ")
|
||||||
if es:
|
if es:
|
||||||
self.curline += " "
|
self.curline += " "
|
||||||
self.endspace = es
|
self.endspace = es
|
||||||
|
|
||||||
def rendertxt(self,xoffset=0):
|
def rendertxt(self,xoffset=0):
|
||||||
result = ''
|
result = ''
|
||||||
lineoff = ""
|
lineoff = ""
|
||||||
for i in range(self.posy):
|
for i in range(self.posy):
|
||||||
result +="\n"
|
result +="\n"
|
||||||
for i in range(self.posx+xoffset):
|
for i in range(self.posx+xoffset):
|
||||||
lineoff+=" "
|
lineoff+=" "
|
||||||
for l in self.lines:
|
for l in self.lines:
|
||||||
result+= lineoff+ l +"\n"
|
result+= lineoff+ l +"\n"
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def renderlines(self,pad=0):
|
def renderlines(self,pad=0):
|
||||||
"""Returns a list of lines, from the current object
|
"""Returns a list of lines, from the current object
|
||||||
pad: all lines must be at least pad characters.
|
pad: all lines must be at least pad characters.
|
||||||
"""
|
"""
|
||||||
result = []
|
result = []
|
||||||
lineoff = ""
|
lineoff = ""
|
||||||
for i in range(self.posx):
|
for i in range(self.posx):
|
||||||
lineoff+=" "
|
lineoff+=" "
|
||||||
for l in self.lines:
|
for l in self.lines:
|
||||||
lpad = ""
|
lpad = ""
|
||||||
if pad and len(l) < pad :
|
if pad and len(l) < pad :
|
||||||
for i in range(pad - len(l)):
|
for i in range(pad - len(l)):
|
||||||
lpad += " "
|
lpad += " "
|
||||||
#elif pad and len(l) > pad ?
|
#elif pad and len(l) > pad ?
|
||||||
result.append(lineoff+ l+lpad)
|
result.append(lineoff+ l+lpad)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def haplines(self,arr,offset,cc= ''):
|
def haplines(self,arr,offset,cc= ''):
|
||||||
""" Horizontaly append lines
|
""" Horizontaly append lines
|
||||||
"""
|
"""
|
||||||
while (len(self.lines) < len(arr)):
|
while (len(self.lines) < len(arr)):
|
||||||
self.lines.append("")
|
self.lines.append("")
|
||||||
|
|
||||||
for i in range(len(self.lines)):
|
for i in range(len(self.lines)):
|
||||||
while (len(self.lines[i]) < offset):
|
while (len(self.lines[i]) < offset):
|
||||||
self.lines[i] += " "
|
self.lines[i] += " "
|
||||||
for i in range(len(arr)):
|
for i in range(len(arr)):
|
||||||
self.lines[i] += cc +arr[i]
|
self.lines[i] += cc +arr[i]
|
||||||
|
|
||||||
|
|
||||||
class _flowable(object):
|
class _flowable(object):
|
||||||
def __init__(self, template, doc,localcontext):
|
def __init__(self, template, doc,localcontext):
|
||||||
|
@ -143,8 +143,8 @@ class _flowable(object):
|
||||||
'1title': self._tag_title,
|
'1title': self._tag_title,
|
||||||
'1spacer': self._tag_spacer,
|
'1spacer': self._tag_spacer,
|
||||||
'para': self._tag_para,
|
'para': self._tag_para,
|
||||||
'font': self._tag_font,
|
'font': self._tag_font,
|
||||||
'section': self._tag_section,
|
'section': self._tag_section,
|
||||||
'1nextFrame': self._tag_next_frame,
|
'1nextFrame': self._tag_next_frame,
|
||||||
'blockTable': self._tag_table,
|
'blockTable': self._tag_table,
|
||||||
'1pageBreak': self._tag_page_break,
|
'1pageBreak': self._tag_page_break,
|
||||||
|
@ -152,15 +152,15 @@ class _flowable(object):
|
||||||
}
|
}
|
||||||
self.template = template
|
self.template = template
|
||||||
self.doc = doc
|
self.doc = doc
|
||||||
self.localcontext = localcontext
|
self.localcontext = localcontext
|
||||||
self.nitags = []
|
self.nitags = []
|
||||||
self.tbox = None
|
self.tbox = None
|
||||||
|
|
||||||
def warn_nitag(self,tag):
|
def warn_nitag(self,tag):
|
||||||
if tag not in self.nitags:
|
if tag not in self.nitags:
|
||||||
verbose("Unknown tag \"%s\", please implement it." % tag)
|
verbose("Unknown tag \"%s\", please implement it." % tag)
|
||||||
self.nitags.append(tag)
|
self.nitags.append(tag)
|
||||||
|
|
||||||
def _tag_page_break(self, node):
|
def _tag_page_break(self, node):
|
||||||
return "\f"
|
return "\f"
|
||||||
|
|
||||||
|
@ -182,79 +182,79 @@ class _flowable(object):
|
||||||
return "\n"*length
|
return "\n"*length
|
||||||
|
|
||||||
def _tag_table(self, node):
|
def _tag_table(self, node):
|
||||||
self.tb.fline()
|
self.tb.fline()
|
||||||
saved_tb = self.tb
|
saved_tb = self.tb
|
||||||
self.tb = None
|
self.tb = None
|
||||||
sizes = None
|
sizes = None
|
||||||
if node.get('colWidths'):
|
if node.get('colWidths'):
|
||||||
sizes = map(lambda x: utils.unit_get(x), node.get('colWidths').split(','))
|
sizes = map(lambda x: utils.unit_get(x), node.get('colWidths').split(','))
|
||||||
trs = []
|
trs = []
|
||||||
for n in utils._child_get(node,self):
|
for n in utils._child_get(node,self):
|
||||||
if n.tag == 'tr':
|
if n.tag == 'tr':
|
||||||
tds = []
|
tds = []
|
||||||
for m in utils._child_get(n,self):
|
for m in utils._child_get(n,self):
|
||||||
if m.tag == 'td':
|
if m.tag == 'td':
|
||||||
self.tb = textbox()
|
self.tb = textbox()
|
||||||
self.rec_render_cnodes(m)
|
self.rec_render_cnodes(m)
|
||||||
tds.append(self.tb)
|
tds.append(self.tb)
|
||||||
self.tb = None
|
self.tb = None
|
||||||
if len(tds):
|
if len(tds):
|
||||||
trs.append(tds)
|
trs.append(tds)
|
||||||
|
|
||||||
if not sizes:
|
if not sizes:
|
||||||
verbose("computing table sizes..")
|
verbose("computing table sizes..")
|
||||||
for tds in trs:
|
for tds in trs:
|
||||||
trt = textbox()
|
trt = textbox()
|
||||||
off=0
|
off=0
|
||||||
for i in range(len(tds)):
|
for i in range(len(tds)):
|
||||||
p = int(sizes[i]/Font_size)
|
p = int(sizes[i]/Font_size)
|
||||||
trl = tds[i].renderlines(pad=p)
|
trl = tds[i].renderlines(pad=p)
|
||||||
trt.haplines(trl,off)
|
trt.haplines(trl,off)
|
||||||
off += sizes[i]/Font_size
|
off += sizes[i]/Font_size
|
||||||
saved_tb.curline = trt
|
saved_tb.curline = trt
|
||||||
saved_tb.fline()
|
saved_tb.fline()
|
||||||
|
|
||||||
self.tb = saved_tb
|
self.tb = saved_tb
|
||||||
return
|
return
|
||||||
|
|
||||||
def _tag_para(self, node):
|
def _tag_para(self, node):
|
||||||
#TODO: styles
|
#TODO: styles
|
||||||
self.rec_render_cnodes(node)
|
self.rec_render_cnodes(node)
|
||||||
self.tb.newline()
|
self.tb.newline()
|
||||||
|
|
||||||
def _tag_section(self, node):
|
def _tag_section(self, node):
|
||||||
#TODO: styles
|
#TODO: styles
|
||||||
self.rec_render_cnodes(node)
|
self.rec_render_cnodes(node)
|
||||||
self.tb.newline()
|
self.tb.newline()
|
||||||
|
|
||||||
def _tag_font(self, node):
|
def _tag_font(self, node):
|
||||||
"""We do ignore fonts.."""
|
"""We do ignore fonts.."""
|
||||||
self.rec_render_cnodes(node)
|
self.rec_render_cnodes(node)
|
||||||
|
|
||||||
def rec_render_cnodes(self,node):
|
def rec_render_cnodes(self,node):
|
||||||
self.tb.appendtxt(utils._process_text(self, node.text or ''))
|
self.tb.appendtxt(utils._process_text(self, node.text or ''))
|
||||||
for n in utils._child_get(node,self):
|
for n in utils._child_get(node,self):
|
||||||
self.rec_render(n)
|
self.rec_render(n)
|
||||||
self.tb.appendtxt(utils._process_text(self, node.tail or ''))
|
self.tb.appendtxt(utils._process_text(self, node.tail or ''))
|
||||||
|
|
||||||
def rec_render(self,node):
|
def rec_render(self,node):
|
||||||
""" Recursive render: fill outarr with text of current node
|
""" Recursive render: fill outarr with text of current node
|
||||||
"""
|
"""
|
||||||
if node.tag != None:
|
if node.tag != None:
|
||||||
if node.tag in self._tags:
|
if node.tag in self._tags:
|
||||||
self._tags[node.tag](node)
|
self._tags[node.tag](node)
|
||||||
else:
|
else:
|
||||||
self.warn_nitag(node.tag)
|
self.warn_nitag(node.tag)
|
||||||
|
|
||||||
def render(self, node):
|
def render(self, node):
|
||||||
self.tb= textbox()
|
self.tb= textbox()
|
||||||
#result = self.template.start()
|
#result = self.template.start()
|
||||||
#result += self.template.frame_start()
|
#result += self.template.frame_start()
|
||||||
self.rec_render_cnodes(node)
|
self.rec_render_cnodes(node)
|
||||||
#result += self.template.frame_stop()
|
#result += self.template.frame_stop()
|
||||||
#result += self.template.end()
|
#result += self.template.end()
|
||||||
result = self.tb.rendertxt()
|
result = self.tb.rendertxt()
|
||||||
del self.tb
|
del self.tb
|
||||||
return result
|
return result
|
||||||
|
|
||||||
class _rml_tmpl_tag(object):
|
class _rml_tmpl_tag(object):
|
||||||
|
@ -274,12 +274,12 @@ class _rml_tmpl_frame(_rml_tmpl_tag):
|
||||||
self.width = width
|
self.width = width
|
||||||
self.posx = posx
|
self.posx = posx
|
||||||
def tag_start(self):
|
def tag_start(self):
|
||||||
return "frame start"
|
return "frame start"
|
||||||
return '<table border="0" width="%d"><tr><td width="%d"> </td><td>' % (self.width+self.posx,self.posx)
|
return '<table border="0" width="%d"><tr><td width="%d"> </td><td>' % (self.width+self.posx,self.posx)
|
||||||
def tag_end(self):
|
def tag_end(self):
|
||||||
return True
|
return True
|
||||||
def tag_stop(self):
|
def tag_stop(self):
|
||||||
return "frame stop"
|
return "frame stop"
|
||||||
return '</td></tr></table><br/>'
|
return '</td></tr></table><br/>'
|
||||||
def tag_mergeable(self):
|
def tag_mergeable(self):
|
||||||
return False
|
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'))]
|
self.pos = [(self.posx, self.posy, align, utils.text_get(node), style.get('td'), style.font_size_get('td'))]
|
||||||
|
|
||||||
def tag_start(self):
|
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()
|
self.pos.sort()
|
||||||
res = '\\table ...'
|
res = '\\table ...'
|
||||||
posx = 0
|
posx = 0
|
||||||
|
@ -335,7 +335,7 @@ class _rml_tmpl_draw_lines(_rml_tmpl_tag):
|
||||||
self.style = style.get('hr')
|
self.style = style.get('hr')
|
||||||
|
|
||||||
def tag_start(self):
|
def tag_start(self):
|
||||||
return "draw lines..\n"
|
return "draw lines..\n"
|
||||||
if self.ok:
|
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)
|
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:
|
else:
|
||||||
|
@ -475,7 +475,7 @@ class _rml_template(object):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def end(self):
|
def end(self):
|
||||||
return "template end\n"
|
return "template end\n"
|
||||||
result = ''
|
result = ''
|
||||||
while not self.loop:
|
while not self.loop:
|
||||||
result += self.frame_start()
|
result += self.frame_start()
|
||||||
|
@ -498,16 +498,16 @@ class _rml_doc(object):
|
||||||
#self.styles = _rml_styles(el,self.localcontext)
|
#self.styles = _rml_styles(el,self.localcontext)
|
||||||
|
|
||||||
el = self.etree.findall('template')
|
el = self.etree.findall('template')
|
||||||
self.result =""
|
self.result =""
|
||||||
if len(el):
|
if len(el):
|
||||||
pt_obj = _rml_template(self.localcontext, out, el[0], self)
|
pt_obj = _rml_template(self.localcontext, out, el[0], self)
|
||||||
stories = utils._child_get(self.etree, self, 'story')
|
stories = utils._child_get(self.etree, self, 'story')
|
||||||
for story in stories:
|
for story in stories:
|
||||||
if self.result:
|
if self.result:
|
||||||
self.result += '\f'
|
self.result += '\f'
|
||||||
f = _flowable(pt_obj,story,self.localcontext)
|
f = _flowable(pt_obj,story,self.localcontext)
|
||||||
self.result += f.render(story)
|
self.result += f.render(story)
|
||||||
del f
|
del f
|
||||||
else:
|
else:
|
||||||
self.result = "<cannot render w/o template>"
|
self.result = "<cannot render w/o template>"
|
||||||
self.result += '\n'
|
self.result += '\n'
|
||||||
|
|
|
@ -46,15 +46,15 @@ except ImportError:
|
||||||
fcntl = None
|
fcntl = None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ssl import SSLError
|
from ssl import SSLError
|
||||||
except ImportError:
|
except ImportError:
|
||||||
class SSLError(Exception): pass
|
class SSLError(Exception): pass
|
||||||
|
|
||||||
class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer):
|
class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer):
|
||||||
""" A threaded httpd server, with all the necessary functionality for us.
|
""" A threaded httpd server, with all the necessary functionality for us.
|
||||||
|
|
||||||
It also inherits the xml-rpc dispatcher, so that some xml-rpc functions
|
It also inherits the xml-rpc dispatcher, so that some xml-rpc functions
|
||||||
will be available to the request handler
|
will be available to the request handler
|
||||||
"""
|
"""
|
||||||
encoding = None
|
encoding = None
|
||||||
allow_none = False
|
allow_none = False
|
||||||
|
@ -81,46 +81,46 @@ class ThreadedHTTPServer(ConnThreadingMixIn, SimpleXMLRPCDispatcher, HTTPServer)
|
||||||
""" Override the error handler
|
""" Override the error handler
|
||||||
"""
|
"""
|
||||||
import traceback
|
import traceback
|
||||||
netsvc.Logger().notifyChannel("init", netsvc.LOG_ERROR,"Server error in request from %s:\n%s" %
|
netsvc.Logger().notifyChannel("init", netsvc.LOG_ERROR,"Server error in request from %s:\n%s" %
|
||||||
(client_address,traceback.format_exc()))
|
(client_address,traceback.format_exc()))
|
||||||
|
|
||||||
class MultiHandler2(MultiHTTPHandler):
|
class MultiHandler2(MultiHTTPHandler):
|
||||||
def log_message(self, format, *args):
|
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):
|
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):
|
class SecureMultiHandler2(SecureMultiHTTPHandler):
|
||||||
def log_message(self, format, *args):
|
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):
|
def getcert_fnames(self):
|
||||||
tc = tools.config
|
tc = tools.config
|
||||||
fcert = tc.get_misc('httpsd','sslcert', 'ssl/server.cert')
|
fcert = tc.get_misc('httpsd','sslcert', 'ssl/server.cert')
|
||||||
fkey = tc.get_misc('httpsd','sslkey', 'ssl/server.key')
|
fkey = tc.get_misc('httpsd','sslkey', 'ssl/server.key')
|
||||||
return (fcert,fkey)
|
return (fcert,fkey)
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
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):
|
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):
|
class HttpDaemon(threading.Thread, netsvc.Server):
|
||||||
def __init__(self, interface, port):
|
def __init__(self, interface, port):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
netsvc.Server.__init__(self)
|
netsvc.Server.__init__(self)
|
||||||
self.__port = port
|
self.__port = port
|
||||||
self.__interface = interface
|
self.__interface = interface
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.server = ThreadedHTTPServer((interface, port), MultiHandler2)
|
self.server = ThreadedHTTPServer((interface, port), MultiHandler2)
|
||||||
self.server.vdirs = []
|
self.server.vdirs = []
|
||||||
self.server.logRequests = True
|
self.server.logRequests = True
|
||||||
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
||||||
"starting HTTP service at %s port %d" % (interface or '0.0.0.0', port,))
|
"starting HTTP service at %s port %d" % (interface or '0.0.0.0', port,))
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
netsvc.Logger().notifyChannel('httpd', netsvc.LOG_CRITICAL, "Error occur when starting the server daemon: %s" % (e,))
|
netsvc.Logger().notifyChannel('httpd', netsvc.LOG_CRITICAL, "Error occur when starting the server daemon: %s" % (e,))
|
||||||
raise
|
raise
|
||||||
|
@ -146,16 +146,16 @@ class HttpDaemon(threading.Thread, netsvc.Server):
|
||||||
class HttpSDaemon(threading.Thread, netsvc.Server):
|
class HttpSDaemon(threading.Thread, netsvc.Server):
|
||||||
def __init__(self, interface, port):
|
def __init__(self, interface, port):
|
||||||
threading.Thread.__init__(self)
|
threading.Thread.__init__(self)
|
||||||
netsvc.Server.__init__(self)
|
netsvc.Server.__init__(self)
|
||||||
self.__port = port
|
self.__port = port
|
||||||
self.__interface = interface
|
self.__interface = interface
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.server = ThreadedHTTPServer((interface, port), SecureMultiHandler2)
|
self.server = ThreadedHTTPServer((interface, port), SecureMultiHandler2)
|
||||||
self.server.vdirs = []
|
self.server.vdirs = []
|
||||||
self.server.logRequests = True
|
self.server.logRequests = True
|
||||||
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
||||||
"starting HTTPS service at %s port %d" % (interface or '0.0.0.0', port,))
|
"starting HTTPS service at %s port %d" % (interface or '0.0.0.0', port,))
|
||||||
except SSLError, e:
|
except SSLError, e:
|
||||||
netsvc.Logger().notifyChannel('httpd-ssl', netsvc.LOG_CRITICAL, "Can not load the certificate and/or the private key files")
|
netsvc.Logger().notifyChannel('httpd-ssl', netsvc.LOG_CRITICAL, "Can not load the certificate and/or the private key files")
|
||||||
raise
|
raise
|
||||||
|
@ -184,32 +184,32 @@ httpd = None
|
||||||
httpsd = None
|
httpsd = None
|
||||||
|
|
||||||
def init_servers():
|
def init_servers():
|
||||||
global httpd, httpsd
|
global httpd, httpsd
|
||||||
if tools.config.get_misc('httpd','enable', True):
|
if tools.config.get_misc('httpd','enable', True):
|
||||||
httpd = HttpDaemon(tools.config.get_misc('httpd','interface', ''), \
|
httpd = HttpDaemon(tools.config.get_misc('httpd','interface', ''), \
|
||||||
tools.config.get_misc('httpd','port', 8069))
|
tools.config.get_misc('httpd','port', 8069))
|
||||||
|
|
||||||
if tools.config.get_misc('httpsd','enable', False):
|
if tools.config.get_misc('httpsd','enable', False):
|
||||||
httpsd = HttpSDaemon(tools.config.get_misc('httpsd','interface', ''), \
|
httpsd = HttpSDaemon(tools.config.get_misc('httpsd','interface', ''), \
|
||||||
tools.config.get_misc('httpsd','port', 8071))
|
tools.config.get_misc('httpsd','port', 8071))
|
||||||
|
|
||||||
def reg_http_service(hts, secure_only = False):
|
def reg_http_service(hts, secure_only = False):
|
||||||
""" Register some handler to httpd.
|
""" Register some handler to httpd.
|
||||||
hts must be an HTTPDir
|
hts must be an HTTPDir
|
||||||
"""
|
"""
|
||||||
global httpd, httpsd
|
global httpd, httpsd
|
||||||
if not isinstance(hts, HTTPDir):
|
if not isinstance(hts, HTTPDir):
|
||||||
raise Exception("Wrong class for http service")
|
raise Exception("Wrong class for http service")
|
||||||
|
|
||||||
if httpd and not secure_only:
|
if httpd and not secure_only:
|
||||||
httpd.server.vdirs.append(hts)
|
httpd.server.vdirs.append(hts)
|
||||||
|
|
||||||
if httpsd:
|
if httpsd:
|
||||||
httpsd.server.vdirs.append(hts)
|
httpsd.server.vdirs.append(hts)
|
||||||
|
|
||||||
if (not httpd) and (not httpsd):
|
if (not httpd) and (not httpsd):
|
||||||
netsvc.Logger().notifyChannel('httpd',netsvc.LOG_WARNING,"No httpd available to register service %s" % hts.path)
|
netsvc.Logger().notifyChannel('httpd',netsvc.LOG_WARNING,"No httpd available to register service %s" % hts.path)
|
||||||
return
|
return
|
||||||
|
|
||||||
import SimpleXMLRPCServer
|
import SimpleXMLRPCServer
|
||||||
class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
|
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)
|
raise xmlrpclib.Fault(tools.exception_to_unicode(e.exception), e.traceback)
|
||||||
|
|
||||||
def log_message(self, format, *args):
|
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):
|
def handle(self):
|
||||||
pass
|
pass
|
||||||
|
@ -233,87 +233,87 @@ class XMLRPCRequestHandler(netsvc.OpenERPDispatcher,FixSendError,SimpleXMLRPCSer
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
self.connection = dummyconn()
|
self.connection = dummyconn()
|
||||||
if not len(XMLRPCRequestHandler.rpc_paths):
|
if not len(XMLRPCRequestHandler.rpc_paths):
|
||||||
XMLRPCRequestHandler.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys())
|
XMLRPCRequestHandler.rpc_paths = map(lambda s: '/%s' % s, netsvc.ExportService._services.keys())
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
def init_xmlrpc():
|
def init_xmlrpc():
|
||||||
if not tools.config.get_misc('xmlrpc','enable', True):
|
if not tools.config.get_misc('xmlrpc','enable', True):
|
||||||
return
|
return
|
||||||
reg_http_service(HTTPDir('/xmlrpc/',XMLRPCRequestHandler))
|
reg_http_service(HTTPDir('/xmlrpc/',XMLRPCRequestHandler))
|
||||||
# Example of http file serving:
|
# Example of http file serving:
|
||||||
# reg_http_service(HTTPDir('/test/',HTTPHandler))
|
# reg_http_service(HTTPDir('/test/',HTTPHandler))
|
||||||
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
netsvc.Logger().notifyChannel("web-services", netsvc.LOG_INFO,
|
||||||
"Registered XML-RPC over HTTP")
|
"Registered XML-RPC over HTTP")
|
||||||
|
|
||||||
|
|
||||||
class OerpAuthProxy(AuthProxy):
|
class OerpAuthProxy(AuthProxy):
|
||||||
""" Require basic authentication..
|
""" Require basic authentication..
|
||||||
|
|
||||||
This is a copy of the BasicAuthProxy, which however checks/caches the db
|
This is a copy of the BasicAuthProxy, which however checks/caches the db
|
||||||
as well.
|
as well.
|
||||||
"""
|
"""
|
||||||
def __init__(self,provider):
|
def __init__(self,provider):
|
||||||
AuthProxy.__init__(self,provider)
|
AuthProxy.__init__(self,provider)
|
||||||
self.auth_creds = {}
|
self.auth_creds = {}
|
||||||
self.auth_tries = 0
|
self.auth_tries = 0
|
||||||
self.last_auth = None
|
self.last_auth = None
|
||||||
|
|
||||||
def checkRequest(self,handler,path = '/'):
|
def checkRequest(self,handler,path = '/'):
|
||||||
if self.auth_creds:
|
if self.auth_creds:
|
||||||
return True
|
return True
|
||||||
auth_str = handler.headers.get('Authorization',False)
|
auth_str = handler.headers.get('Authorization',False)
|
||||||
try:
|
try:
|
||||||
db = handler.get_db_from_path(path)
|
db = handler.get_db_from_path(path)
|
||||||
print "Got db:",db
|
print "Got db:",db
|
||||||
except:
|
except:
|
||||||
if path.startswith('/'):
|
if path.startswith('/'):
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
psp= path.split('/')
|
psp= path.split('/')
|
||||||
if len(psp)>1:
|
if len(psp)>1:
|
||||||
db = psp[0]
|
db = psp[0]
|
||||||
else:
|
else:
|
||||||
#FIXME!
|
#FIXME!
|
||||||
self.provider.log("Wrong path: %s, failing auth" %path)
|
self.provider.log("Wrong path: %s, failing auth" %path)
|
||||||
raise AuthRejectedExc("Authorization failed. Wrong sub-path.")
|
raise AuthRejectedExc("Authorization failed. Wrong sub-path.")
|
||||||
|
|
||||||
if auth_str and auth_str.startswith('Basic '):
|
if auth_str and auth_str.startswith('Basic '):
|
||||||
auth_str=auth_str[len('Basic '):]
|
auth_str=auth_str[len('Basic '):]
|
||||||
(user,passwd) = base64.decodestring(auth_str).split(':')
|
(user,passwd) = base64.decodestring(auth_str).split(':')
|
||||||
self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db))
|
self.provider.log("Found user=\"%s\", passwd=\"***\" for db=\"%s\"" %(user,db))
|
||||||
acd = self.provider.authenticate(db,user,passwd,handler.client_address)
|
acd = self.provider.authenticate(db,user,passwd,handler.client_address)
|
||||||
if acd != False:
|
if acd != False:
|
||||||
self.auth_creds[db] = acd
|
self.auth_creds[db] = acd
|
||||||
self.last_auth=db
|
self.last_auth=db
|
||||||
return True
|
return True
|
||||||
if self.auth_tries > 5:
|
if self.auth_tries > 5:
|
||||||
self.provider.log("Failing authorization after 5 requests w/o password")
|
self.provider.log("Failing authorization after 5 requests w/o password")
|
||||||
raise AuthRejectedExc("Authorization failed.")
|
raise AuthRejectedExc("Authorization failed.")
|
||||||
self.auth_tries += 1
|
self.auth_tries += 1
|
||||||
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
|
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
|
||||||
|
|
||||||
import security
|
import security
|
||||||
class OpenERPAuthProvider(AuthProvider):
|
class OpenERPAuthProvider(AuthProvider):
|
||||||
def __init__(self,realm = 'OpenERP User'):
|
def __init__(self,realm = 'OpenERP User'):
|
||||||
self.realm = realm
|
self.realm = realm
|
||||||
|
|
||||||
def setupAuth(self, multi, handler):
|
def setupAuth(self, multi, handler):
|
||||||
if not multi.sec_realms.has_key(self.realm):
|
if not multi.sec_realms.has_key(self.realm):
|
||||||
multi.sec_realms[self.realm] = OerpAuthProxy(self)
|
multi.sec_realms[self.realm] = OerpAuthProxy(self)
|
||||||
handler.auth_proxy = multi.sec_realms[self.realm]
|
handler.auth_proxy = multi.sec_realms[self.realm]
|
||||||
|
|
||||||
def authenticate(self, db, user, passwd, client_address):
|
def authenticate(self, db, user, passwd, client_address):
|
||||||
try:
|
try:
|
||||||
uid = security.login(db,user,passwd)
|
uid = security.login(db,user,passwd)
|
||||||
if uid is False:
|
if uid is False:
|
||||||
return False
|
return False
|
||||||
return (user, passwd, db, uid)
|
return (user, passwd, db, uid)
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
netsvc.Logger().notifyChannel("auth",netsvc.LOG_DEBUG,"Fail auth:"+ str(e))
|
netsvc.Logger().notifyChannel("auth",netsvc.LOG_DEBUG,"Fail auth:"+ str(e))
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def log(self, msg):
|
def log(self, msg):
|
||||||
netsvc.Logger().notifyChannel("auth",netsvc.LOG_INFO,msg)
|
netsvc.Logger().notifyChannel("auth",netsvc.LOG_INFO,msg)
|
||||||
|
|
||||||
#eof
|
#eof
|
||||||
|
|
|
@ -141,23 +141,23 @@ class TinySocketServerThread(threading.Thread,netsvc.Server):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def stats(self):
|
def stats(self):
|
||||||
res = "Net-RPC: " + ( (self.running and "running") or "stopped")
|
res = "Net-RPC: " + ( (self.running and "running") or "stopped")
|
||||||
i = 0
|
i = 0
|
||||||
for t in self.threads:
|
for t in self.threads:
|
||||||
i += 1
|
i += 1
|
||||||
res += "\nNet-RPC #%d: %s " % (i, t.name)
|
res += "\nNet-RPC #%d: %s " % (i, t.name)
|
||||||
if t.isAlive():
|
if t.isAlive():
|
||||||
res += "running"
|
res += "running"
|
||||||
else:
|
else:
|
||||||
res += "finished"
|
res += "finished"
|
||||||
if t.sock:
|
if t.sock:
|
||||||
res += ", socket"
|
res += ", socket"
|
||||||
return res
|
return res
|
||||||
|
|
||||||
netrpcd = None
|
netrpcd = None
|
||||||
|
|
||||||
def init_servers():
|
def init_servers():
|
||||||
global netrpcd
|
global netrpcd
|
||||||
if tools.config.get_misc('netrpcd','enable', True):
|
if tools.config.get_misc('netrpcd','enable', True):
|
||||||
netrpcd = TinySocketServerThread(tools.config.get_misc('netrpcd','interface', ''), \
|
netrpcd = TinySocketServerThread(tools.config.get_misc('netrpcd','interface', ''), \
|
||||||
tools.config.get_misc('netrpcd','port', 8070))
|
tools.config.get_misc('netrpcd','port', 8070))
|
||||||
|
|
|
@ -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
|
self._pg_psw_env_var_is_set = False # on win32, pg_dump need the PGPASSWORD env var
|
||||||
|
|
||||||
def dispatch(self, method, auth, params):
|
def dispatch(self, method, auth, params):
|
||||||
if method in [ 'create', 'get_progress', 'drop', 'dump',
|
if method in [ 'create', 'get_progress', 'drop', 'dump',
|
||||||
'restore', 'rename',
|
'restore', 'rename',
|
||||||
'change_admin_password', 'migrate_databases' ]:
|
'change_admin_password', 'migrate_databases' ]:
|
||||||
passwd = params[0]
|
passwd = params[0]
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
security.check_super(passwd)
|
security.check_super(passwd)
|
||||||
elif method in [ 'db_exist', 'list', 'list_lang', 'server_version' ]:
|
elif method in [ 'db_exist', 'list', 'list_lang', 'server_version' ]:
|
||||||
# params = params
|
# params = params
|
||||||
# No security check for these methods
|
# No security check for these methods
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise KeyError("Method not found: %s" % method)
|
raise KeyError("Method not found: %s" % method)
|
||||||
fn = getattr(self, 'exp_'+method)
|
fn = getattr(self, 'exp_'+method)
|
||||||
return fn(*params)
|
return fn(*params)
|
||||||
|
|
||||||
def new_dispatch(self,method,auth,params):
|
def new_dispatch(self,method,auth,params):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exp_create(self, db_name, demo, lang, user_password='admin'):
|
def exp_create(self, db_name, demo, lang, user_password='admin'):
|
||||||
self.id_protect.acquire()
|
self.id_protect.acquire()
|
||||||
|
@ -366,15 +366,15 @@ class _ObjectService(netsvc.ExportService):
|
||||||
"A common base class for those who have fn(db, uid, password,...) "
|
"A common base class for those who have fn(db, uid, password,...) "
|
||||||
|
|
||||||
def common_dispatch(self, method, auth, params):
|
def common_dispatch(self, method, auth, params):
|
||||||
(db, uid, passwd ) = params[0:3]
|
(db, uid, passwd ) = params[0:3]
|
||||||
params = params[3:]
|
params = params[3:]
|
||||||
security.check(db,uid,passwd)
|
security.check(db,uid,passwd)
|
||||||
cr = pooler.get_db(db).cursor()
|
cr = pooler.get_db(db).cursor()
|
||||||
fn = getattr(self, 'exp_'+method)
|
fn = getattr(self, 'exp_'+method)
|
||||||
res = fn(cr, uid, *params)
|
res = fn(cr, uid, *params)
|
||||||
cr.commit()
|
cr.commit()
|
||||||
cr.close()
|
cr.close()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
class common(_ObjectService):
|
class common(_ObjectService):
|
||||||
def __init__(self,name="common"):
|
def __init__(self,name="common"):
|
||||||
|
@ -382,36 +382,36 @@ class common(_ObjectService):
|
||||||
self.joinGroup("web-services")
|
self.joinGroup("web-services")
|
||||||
|
|
||||||
def dispatch(self, method, auth, params):
|
def dispatch(self, method, auth, params):
|
||||||
logger = netsvc.Logger()
|
logger = netsvc.Logger()
|
||||||
if method in [ 'ir_set','ir_del', 'ir_get' ]:
|
if method in [ 'ir_set','ir_del', 'ir_get' ]:
|
||||||
return self.common_dispatch(method,auth,params)
|
return self.common_dispatch(method,auth,params)
|
||||||
if method == 'login':
|
if method == 'login':
|
||||||
# At this old dispatcher, we do NOT update the auth proxy
|
# At this old dispatcher, we do NOT update the auth proxy
|
||||||
res = security.login(params[0], params[1], params[2])
|
res = security.login(params[0], params[1], params[2])
|
||||||
msg = res and 'successful login' or 'bad login or password'
|
msg = res and 'successful login' or 'bad login or password'
|
||||||
# TODO log the client ip address..
|
# 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()))
|
logger.notifyChannel("web-service", netsvc.LOG_INFO, "%s from '%s' using database '%s'" % (msg, params[1], params[0].lower()))
|
||||||
return res or False
|
return res or False
|
||||||
elif method == 'logout':
|
elif method == 'logout':
|
||||||
if auth:
|
if auth:
|
||||||
auth.logout(params[1])
|
auth.logout(params[1])
|
||||||
logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db))
|
logger.notifyChannel("web-service", netsvc.LOG_INFO,'Logout %s from database %s'%(login,db))
|
||||||
return True
|
return True
|
||||||
elif method in ['about', 'timezone_get', 'get_server_environment', 'login_message', 'get_stats' ]:
|
elif method in ['about', 'timezone_get', 'get_server_environment', 'login_message', 'get_stats' ]:
|
||||||
pass
|
pass
|
||||||
elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel']:
|
elif method in ['get_available_updates', 'get_migration_scripts', 'set_loglevel']:
|
||||||
passwd = params[0]
|
passwd = params[0]
|
||||||
params = params[1:]
|
params = params[1:]
|
||||||
security.check_super(passwd)
|
security.check_super(passwd)
|
||||||
else:
|
else:
|
||||||
raise Exception("Method not found: %s" % method)
|
raise Exception("Method not found: %s" % method)
|
||||||
|
|
||||||
fn = getattr(self, 'exp_'+method)
|
fn = getattr(self, 'exp_'+method)
|
||||||
return fn(*params)
|
return fn(*params)
|
||||||
|
|
||||||
|
|
||||||
def new_dispatch(self,method,auth,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):
|
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)
|
res = ir.ir_set(cr,uid, keys, args, name, value, replace, isobject)
|
||||||
|
@ -574,7 +574,7 @@ GNU Public Licence.
|
||||||
def exp_get_stats(self):
|
def exp_get_stats(self):
|
||||||
import threading
|
import threading
|
||||||
res = "OpenERP server: %d threads\n" % threading.active_count()
|
res = "OpenERP server: %d threads\n" % threading.active_count()
|
||||||
res += netsvc.Server.allStats()
|
res += netsvc.Server.allStats()
|
||||||
return res
|
return res
|
||||||
|
|
||||||
common()
|
common()
|
||||||
|
@ -585,19 +585,19 @@ class objects_proxy(netsvc.ExportService):
|
||||||
self.joinGroup('web-services')
|
self.joinGroup('web-services')
|
||||||
|
|
||||||
def dispatch(self, method, auth, params):
|
def dispatch(self, method, auth, params):
|
||||||
(db, uid, passwd ) = params[0:3]
|
(db, uid, passwd ) = params[0:3]
|
||||||
params = params[3:]
|
params = params[3:]
|
||||||
if method not in ['execute','exec_workflow','obj_list']:
|
if method not in ['execute','exec_workflow','obj_list']:
|
||||||
raise KeyError("Method not supported %s" % method)
|
raise KeyError("Method not supported %s" % method)
|
||||||
security.check(db,uid,passwd)
|
security.check(db,uid,passwd)
|
||||||
ls = netsvc.LocalService('object_proxy')
|
ls = netsvc.LocalService('object_proxy')
|
||||||
fn = getattr(ls, method)
|
fn = getattr(ls, method)
|
||||||
res = fn(db, uid, *params)
|
res = fn(db, uid, *params)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def new_dispatch(self,method,auth,params):
|
def new_dispatch(self,method,auth,params):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
objects_proxy()
|
objects_proxy()
|
||||||
|
|
||||||
|
@ -623,17 +623,17 @@ class wizard(netsvc.ExportService):
|
||||||
self.wiz_uid = {}
|
self.wiz_uid = {}
|
||||||
|
|
||||||
def dispatch(self, method, auth, params):
|
def dispatch(self, method, auth, params):
|
||||||
(db, uid, passwd ) = params[0:3]
|
(db, uid, passwd ) = params[0:3]
|
||||||
params = params[3:]
|
params = params[3:]
|
||||||
if method not in ['execute','create']:
|
if method not in ['execute','create']:
|
||||||
raise KeyError("Method not supported %s" % method)
|
raise KeyError("Method not supported %s" % method)
|
||||||
security.check(db,uid,passwd)
|
security.check(db,uid,passwd)
|
||||||
fn = getattr(self, 'exp_'+method)
|
fn = getattr(self, 'exp_'+method)
|
||||||
res = fn(db, uid, *params)
|
res = fn(db, uid, *params)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def new_dispatch(self,method,auth,params):
|
def new_dispatch(self,method,auth,params):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _execute(self, db, uid, wiz_id, datas, action, context):
|
def _execute(self, db, uid, wiz_id, datas, action, context):
|
||||||
self.wiz_datas[wiz_id].update(datas)
|
self.wiz_datas[wiz_id].update(datas)
|
||||||
|
@ -685,18 +685,18 @@ class report_spool(netsvc.ExportService):
|
||||||
self.id_protect = threading.Semaphore()
|
self.id_protect = threading.Semaphore()
|
||||||
|
|
||||||
def dispatch(self, method, auth, params):
|
def dispatch(self, method, auth, params):
|
||||||
(db, uid, passwd ) = params[0:3]
|
(db, uid, passwd ) = params[0:3]
|
||||||
params = params[3:]
|
params = params[3:]
|
||||||
if method not in ['report','report_get']:
|
if method not in ['report','report_get']:
|
||||||
raise KeyError("Method not supported %s" % method)
|
raise KeyError("Method not supported %s" % method)
|
||||||
security.check(db,uid,passwd)
|
security.check(db,uid,passwd)
|
||||||
fn = getattr(self, 'exp_' + method)
|
fn = getattr(self, 'exp_' + method)
|
||||||
res = fn(db, uid, *params)
|
res = fn(db, uid, *params)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
||||||
def new_dispatch(self,method,auth,params):
|
def new_dispatch(self,method,auth,params):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exp_report(self, db, uid, object, ids, datas=None, context=None):
|
def exp_report(self, db, uid, object, ids, datas=None, context=None):
|
||||||
if not datas:
|
if not datas:
|
||||||
|
|
|
@ -37,115 +37,115 @@ from BaseHTTPServer import *
|
||||||
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
from SimpleHTTPServer import SimpleHTTPRequestHandler
|
||||||
|
|
||||||
class AuthRequiredExc(Exception):
|
class AuthRequiredExc(Exception):
|
||||||
def __init__(self,atype,realm):
|
def __init__(self,atype,realm):
|
||||||
Exception.__init__(self)
|
Exception.__init__(self)
|
||||||
self.atype = atype
|
self.atype = atype
|
||||||
self.realm = realm
|
self.realm = realm
|
||||||
|
|
||||||
class AuthRejectedExc(Exception):
|
class AuthRejectedExc(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class AuthProvider:
|
class AuthProvider:
|
||||||
def __init__(self,realm):
|
def __init__(self,realm):
|
||||||
self.realm = realm
|
self.realm = realm
|
||||||
|
|
||||||
def setupAuth(self, multi,handler):
|
def setupAuth(self, multi,handler):
|
||||||
""" Attach an AuthProxy object to handler
|
""" Attach an AuthProxy object to handler
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def authenticate(self, user, passwd, client_address):
|
def authenticate(self, user, passwd, client_address):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def log(self, msg):
|
def log(self, msg):
|
||||||
print msg
|
print msg
|
||||||
|
|
||||||
class BasicAuthProvider(AuthProvider):
|
class BasicAuthProvider(AuthProvider):
|
||||||
def setupAuth(self, multi, handler):
|
def setupAuth(self, multi, handler):
|
||||||
if not multi.sec_realms.has_key(self.realm):
|
if not multi.sec_realms.has_key(self.realm):
|
||||||
multi.sec_realms[self.realm] = BasicAuthProxy(self)
|
multi.sec_realms[self.realm] = BasicAuthProxy(self)
|
||||||
|
|
||||||
|
|
||||||
class AuthProxy:
|
class AuthProxy:
|
||||||
""" This class will hold authentication information for a handler,
|
""" This class will hold authentication information for a handler,
|
||||||
i.e. a connection
|
i.e. a connection
|
||||||
"""
|
"""
|
||||||
def __init__(self, provider):
|
def __init__(self, provider):
|
||||||
self.provider = provider
|
self.provider = provider
|
||||||
|
|
||||||
def checkRequest(self,handler,path = '/'):
|
def checkRequest(self,handler,path = '/'):
|
||||||
""" Check if we are allowed to process that request
|
""" Check if we are allowed to process that request
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class BasicAuthProxy(AuthProxy):
|
class BasicAuthProxy(AuthProxy):
|
||||||
""" Require basic authentication..
|
""" Require basic authentication..
|
||||||
"""
|
"""
|
||||||
def __init__(self,provider):
|
def __init__(self,provider):
|
||||||
AuthProxy.__init__(self,provider)
|
AuthProxy.__init__(self,provider)
|
||||||
self.auth_creds = None
|
self.auth_creds = None
|
||||||
self.auth_tries = 0
|
self.auth_tries = 0
|
||||||
|
|
||||||
def checkRequest(self,handler,path = '/'):
|
def checkRequest(self,handler,path = '/'):
|
||||||
if self.auth_creds:
|
if self.auth_creds:
|
||||||
return True
|
return True
|
||||||
auth_str = handler.headers.get('Authorization',False)
|
auth_str = handler.headers.get('Authorization',False)
|
||||||
if auth_str and auth_str.startswith('Basic '):
|
if auth_str and auth_str.startswith('Basic '):
|
||||||
auth_str=auth_str[len('Basic '):]
|
auth_str=auth_str[len('Basic '):]
|
||||||
(user,passwd) = base64.decodestring(auth_str).split(':')
|
(user,passwd) = base64.decodestring(auth_str).split(':')
|
||||||
self.provider.log("Found user=\"%s\", passwd=\"%s\"" %(user,passwd))
|
self.provider.log("Found user=\"%s\", passwd=\"%s\"" %(user,passwd))
|
||||||
self.auth_creds = self.provider.authenticate(user,passwd,handler.client_address)
|
self.auth_creds = self.provider.authenticate(user,passwd,handler.client_address)
|
||||||
if self.auth_creds:
|
if self.auth_creds:
|
||||||
return True
|
return True
|
||||||
if self.auth_tries > 5:
|
if self.auth_tries > 5:
|
||||||
self.provider.log("Failing authorization after 5 requests w/o password")
|
self.provider.log("Failing authorization after 5 requests w/o password")
|
||||||
raise AuthRejectedExc("Authorization failed.")
|
raise AuthRejectedExc("Authorization failed.")
|
||||||
self.auth_tries += 1
|
self.auth_tries += 1
|
||||||
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
|
raise AuthRequiredExc(atype = 'Basic', realm=self.provider.realm)
|
||||||
|
|
||||||
|
|
||||||
class HTTPHandler(SimpleHTTPRequestHandler):
|
class HTTPHandler(SimpleHTTPRequestHandler):
|
||||||
def __init__(self,request, client_address, server):
|
def __init__(self,request, client_address, server):
|
||||||
SimpleHTTPRequestHandler.__init__(self,request,client_address,server)
|
SimpleHTTPRequestHandler.__init__(self,request,client_address,server)
|
||||||
# print "Handler for %s inited" % str(client_address)
|
# print "Handler for %s inited" % str(client_address)
|
||||||
self.protocol_version = 'HTTP/1.1'
|
self.protocol_version = 'HTTP/1.1'
|
||||||
self.connection = dummyconn()
|
self.connection = dummyconn()
|
||||||
|
|
||||||
def handle(self):
|
def handle(self):
|
||||||
""" Classes here should NOT handle inside their constructor
|
""" Classes here should NOT handle inside their constructor
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def finish(self):
|
def finish(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class HTTPDir:
|
class HTTPDir:
|
||||||
""" A dispatcher class, like a virtual folder in httpd
|
""" A dispatcher class, like a virtual folder in httpd
|
||||||
"""
|
"""
|
||||||
def __init__(self,path,handler, auth_provider = None):
|
def __init__(self,path,handler, auth_provider = None):
|
||||||
self.path = path
|
self.path = path
|
||||||
self.handler = handler
|
self.handler = handler
|
||||||
self.auth_provider = auth_provider
|
self.auth_provider = auth_provider
|
||||||
|
|
||||||
def matches(self, request):
|
def matches(self, request):
|
||||||
""" Test if some request matches us. If so, return
|
""" Test if some request matches us. If so, return
|
||||||
the matched path. """
|
the matched path. """
|
||||||
if request.startswith(self.path):
|
if request.startswith(self.path):
|
||||||
return self.path
|
return self.path
|
||||||
return False
|
return False
|
||||||
|
|
||||||
class noconnection:
|
class noconnection:
|
||||||
""" a class to use instead of the real connection
|
""" a class to use instead of the real connection
|
||||||
"""
|
"""
|
||||||
def makefile(self, mode, bufsize):
|
def makefile(self, mode, bufsize):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
class dummyconn:
|
class dummyconn:
|
||||||
def shutdown(self, tru):
|
def shutdown(self, tru):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _quote_html(html):
|
def _quote_html(html):
|
||||||
return html.replace("&", "&").replace("<", "<").replace(">", ">")
|
return html.replace("&", "&").replace("<", "<").replace(">", ">")
|
||||||
|
@ -168,7 +168,7 @@ class FixSendError:
|
||||||
self.send_response(code, message)
|
self.send_response(code, message)
|
||||||
self.send_header("Content-Type", self.error_content_type)
|
self.send_header("Content-Type", self.error_content_type)
|
||||||
self.send_header('Connection', 'close')
|
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()
|
self.end_headers()
|
||||||
if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
|
if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
|
||||||
self.wfile.write(content)
|
self.wfile.write(content)
|
||||||
|
@ -176,65 +176,65 @@ class FixSendError:
|
||||||
class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
|
class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
|
||||||
""" this is a multiple handler, that will dispatch each request
|
""" this is a multiple handler, that will dispatch each request
|
||||||
to a nested handler, iff it matches
|
to a nested handler, iff it matches
|
||||||
|
|
||||||
The handler will also have *one* dict of authentication proxies,
|
The handler will also have *one* dict of authentication proxies,
|
||||||
groupped by their realm.
|
groupped by their realm.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
protocol_version = "HTTP/1.1"
|
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>
|
auth_required_msg = """ <html><head><title>Authorization required</title></head>
|
||||||
<body>You must authenticate to use this service</body><html>\r\r"""
|
<body>You must authenticate to use this service</body><html>\r\r"""
|
||||||
|
|
||||||
def __init__(self, request, client_address, server):
|
def __init__(self, request, client_address, server):
|
||||||
self.in_handlers = {}
|
self.in_handlers = {}
|
||||||
self.sec_realms = {}
|
self.sec_realms = {}
|
||||||
SocketServer.StreamRequestHandler.__init__(self,request,client_address,server)
|
SocketServer.StreamRequestHandler.__init__(self,request,client_address,server)
|
||||||
self.log_message("MultiHttpHandler init for %s" %(str(client_address)))
|
self.log_message("MultiHttpHandler init for %s" %(str(client_address)))
|
||||||
|
|
||||||
def _handle_one_foreign(self,fore, path, auth_provider):
|
def _handle_one_foreign(self,fore, path, auth_provider):
|
||||||
""" This method overrides the handle_one_request for *children*
|
""" This method overrides the handle_one_request for *children*
|
||||||
handlers. It is required, since the first line should not be
|
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)
|
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
|
if not fore.parse_request(): # An error code has been sent, just exit
|
||||||
return
|
return
|
||||||
self.request_version = fore.request_version
|
self.request_version = fore.request_version
|
||||||
if auth_provider and auth_provider.realm:
|
if auth_provider and auth_provider.realm:
|
||||||
try:
|
try:
|
||||||
self.sec_realms[auth_provider.realm].checkRequest(fore,path)
|
self.sec_realms[auth_provider.realm].checkRequest(fore,path)
|
||||||
except AuthRequiredExc,ae:
|
except AuthRequiredExc,ae:
|
||||||
if self.request_version != 'HTTP/1.1':
|
if self.request_version != 'HTTP/1.1':
|
||||||
self.log_error("Cannot require auth at %s",self.request_version)
|
self.log_error("Cannot require auth at %s",self.request_version)
|
||||||
self.send_error(401)
|
self.send_error(401)
|
||||||
return
|
return
|
||||||
self._get_ignore_body(fore) # consume any body that came, not loose sync with input
|
self._get_ignore_body(fore) # consume any body that came, not loose sync with input
|
||||||
self.send_response(401,'Authorization required')
|
self.send_response(401,'Authorization required')
|
||||||
self.send_header('WWW-Authenticate','%s realm="%s"' % (ae.atype,ae.realm))
|
self.send_header('WWW-Authenticate','%s realm="%s"' % (ae.atype,ae.realm))
|
||||||
self.send_header('Connection', 'keep-alive')
|
self.send_header('Connection', 'keep-alive')
|
||||||
self.send_header('Content-Type','text/html')
|
self.send_header('Content-Type','text/html')
|
||||||
self.send_header('Content-Length',len(self.auth_required_msg))
|
self.send_header('Content-Length',len(self.auth_required_msg))
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(self.auth_required_msg)
|
self.wfile.write(self.auth_required_msg)
|
||||||
return
|
return
|
||||||
except AuthRejectedExc,e:
|
except AuthRejectedExc,e:
|
||||||
self.log_error("Rejected auth: %s" % e.args[0])
|
self.log_error("Rejected auth: %s" % e.args[0])
|
||||||
self.send_error(401,e.args[0])
|
self.send_error(401,e.args[0])
|
||||||
self.close_connection = 1
|
self.close_connection = 1
|
||||||
return
|
return
|
||||||
mname = 'do_' + fore.command
|
mname = 'do_' + fore.command
|
||||||
if not hasattr(fore, mname):
|
if not hasattr(fore, mname):
|
||||||
fore.send_error(501, "Unsupported method (%r)" % fore.command)
|
fore.send_error(501, "Unsupported method (%r)" % fore.command)
|
||||||
return
|
return
|
||||||
fore.close_connection = 0
|
fore.close_connection = 0
|
||||||
method = getattr(fore, mname)
|
method = getattr(fore, mname)
|
||||||
method()
|
method()
|
||||||
if fore.close_connection:
|
if fore.close_connection:
|
||||||
# print "Closing connection because of handler"
|
# print "Closing connection because of handler"
|
||||||
self.close_connection = fore.close_connection
|
self.close_connection = fore.close_connection
|
||||||
|
|
||||||
def parse_rawline(self):
|
def parse_rawline(self):
|
||||||
"""Parse a request (internal).
|
"""Parse a request (internal).
|
||||||
|
@ -295,67 +295,67 @@ class MultiHTTPHandler(FixSendError,BaseHTTPRequestHandler):
|
||||||
else:
|
else:
|
||||||
self.send_error(400, "Bad request syntax (%r)" % requestline)
|
self.send_error(400, "Bad request syntax (%r)" % requestline)
|
||||||
return False
|
return False
|
||||||
self.request_version = version
|
self.request_version = version
|
||||||
self.command, self.path, self.version = command, path, version
|
self.command, self.path, self.version = command, path, version
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def handle_one_request(self):
|
def handle_one_request(self):
|
||||||
"""Handle a single HTTP request.
|
"""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()
|
self.raw_requestline = self.rfile.readline()
|
||||||
if not self.raw_requestline:
|
if not self.raw_requestline:
|
||||||
self.close_connection = 1
|
self.close_connection = 1
|
||||||
# self.log_message("no requestline, connection closed?")
|
# self.log_message("no requestline, connection closed?")
|
||||||
return
|
return
|
||||||
if not self.parse_rawline():
|
if not self.parse_rawline():
|
||||||
self.log_message("Could not parse rawline.")
|
self.log_message("Could not parse rawline.")
|
||||||
return
|
return
|
||||||
# self.parse_request(): # Do NOT parse here. the first line should be the only
|
# self.parse_request(): # Do NOT parse here. the first line should be the only
|
||||||
for vdir in self.server.vdirs:
|
for vdir in self.server.vdirs:
|
||||||
p = vdir.matches(self.path)
|
p = vdir.matches(self.path)
|
||||||
if p == False:
|
if p == False:
|
||||||
continue
|
continue
|
||||||
npath = self.path[len(p):]
|
npath = self.path[len(p):]
|
||||||
if not npath.startswith('/'):
|
if not npath.startswith('/'):
|
||||||
npath = '/' + npath
|
npath = '/' + npath
|
||||||
|
|
||||||
if not self.in_handlers.has_key(p):
|
if not self.in_handlers.has_key(p):
|
||||||
self.in_handlers[p] = vdir.handler(noconnection(),self.client_address,self.server)
|
self.in_handlers[p] = vdir.handler(noconnection(),self.client_address,self.server)
|
||||||
if vdir.auth_provider:
|
if vdir.auth_provider:
|
||||||
vdir.auth_provider.setupAuth(self, self.in_handlers[p])
|
vdir.auth_provider.setupAuth(self, self.in_handlers[p])
|
||||||
hnd = self.in_handlers[p]
|
hnd = self.in_handlers[p]
|
||||||
hnd.rfile = self.rfile
|
hnd.rfile = self.rfile
|
||||||
hnd.wfile = self.wfile
|
hnd.wfile = self.wfile
|
||||||
self.rlpath = self.raw_requestline
|
self.rlpath = self.raw_requestline
|
||||||
self._handle_one_foreign(hnd,npath, vdir.auth_provider)
|
self._handle_one_foreign(hnd,npath, vdir.auth_provider)
|
||||||
# print "Handled, closing = ", self.close_connection
|
# print "Handled, closing = ", self.close_connection
|
||||||
return
|
return
|
||||||
# if no match:
|
# if no match:
|
||||||
self.send_error(404, "Path not found: %s" % self.path)
|
self.send_error(404, "Path not found: %s" % self.path)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _get_ignore_body(self,fore):
|
def _get_ignore_body(self,fore):
|
||||||
if not fore.headers.has_key("content-length"):
|
if not fore.headers.has_key("content-length"):
|
||||||
return
|
return
|
||||||
max_chunk_size = 10*1024*1024
|
max_chunk_size = 10*1024*1024
|
||||||
size_remaining = int(fore.headers["content-length"])
|
size_remaining = int(fore.headers["content-length"])
|
||||||
got = ''
|
got = ''
|
||||||
while size_remaining:
|
while size_remaining:
|
||||||
chunk_size = min(size_remaining, max_chunk_size)
|
chunk_size = min(size_remaining, max_chunk_size)
|
||||||
got = fore.rfile.read(chunk_size)
|
got = fore.rfile.read(chunk_size)
|
||||||
size_remaining -= len(got)
|
size_remaining -= len(got)
|
||||||
|
|
||||||
|
|
||||||
class SecureMultiHTTPHandler(MultiHTTPHandler):
|
class SecureMultiHTTPHandler(MultiHTTPHandler):
|
||||||
def getcert_fnames(self):
|
def getcert_fnames(self):
|
||||||
""" Return a pair with the filenames of ssl cert,key
|
""" Return a pair with the filenames of ssl cert,key
|
||||||
|
|
||||||
Override this to direct to other filenames
|
Override this to direct to other filenames
|
||||||
"""
|
"""
|
||||||
return ('server.cert','server.key')
|
return ('server.cert','server.key')
|
||||||
|
|
||||||
def setup(self):
|
def setup(self):
|
||||||
import ssl
|
import ssl
|
||||||
certfile, keyfile = self.getcert_fnames()
|
certfile, keyfile = self.getcert_fnames()
|
||||||
|
@ -386,10 +386,10 @@ import threading
|
||||||
class ConnThreadingMixIn:
|
class ConnThreadingMixIn:
|
||||||
"""Mix-in class to handle each _connection_ in a new thread.
|
"""Mix-in class to handle each _connection_ in a new thread.
|
||||||
|
|
||||||
This is necessary for persistent connections, where multiple
|
This is necessary for persistent connections, where multiple
|
||||||
requests should be handled synchronously at each connection, but
|
requests should be handled synchronously at each connection, but
|
||||||
multiple connections can run in parallel.
|
multiple connections can run in parallel.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Decides how threads will act upon termination of the
|
# Decides how threads will act upon termination of the
|
||||||
# main process
|
# main process
|
||||||
|
@ -401,7 +401,7 @@ class ConnThreadingMixIn:
|
||||||
if self.daemon_threads:
|
if self.daemon_threads:
|
||||||
t.setDaemon (1)
|
t.setDaemon (1)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
def _handle_request2(self):
|
def _handle_request2(self):
|
||||||
"""Handle one request, without blocking.
|
"""Handle one request, without blocking.
|
||||||
|
|
||||||
|
|
|
@ -119,14 +119,14 @@ class Cursor(object):
|
||||||
try:
|
try:
|
||||||
params = params or None
|
params = params or None
|
||||||
res = self._obj.execute(query, params)
|
res = self._obj.execute(query, params)
|
||||||
except psycopg2.ProgrammingError, pe:
|
except psycopg2.ProgrammingError, pe:
|
||||||
logger= netsvc.Logger()
|
logger= netsvc.Logger()
|
||||||
logger.notifyChannel('sql_db', netsvc.LOG_ERROR, "Programming error: %s, in query %s" % (pe, query))
|
logger.notifyChannel('sql_db', netsvc.LOG_ERROR, "Programming error: %s, in query %s" % (pe, query))
|
||||||
raise
|
raise
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
log("bad query: %s" % self._obj.query)
|
log("bad query: %s" % self._obj.query)
|
||||||
log(e)
|
log(e)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
if self.sql_log:
|
if self.sql_log:
|
||||||
log("query: %s" % self._obj.query)
|
log("query: %s" % self._obj.query)
|
||||||
|
@ -144,8 +144,8 @@ class Cursor(object):
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def print_log(self):
|
def print_log(self):
|
||||||
global sql_counter
|
global sql_counter
|
||||||
sql_counter += self.count
|
sql_counter += self.count
|
||||||
def process(type):
|
def process(type):
|
||||||
sqllogs = {'from':self.sql_from_log, 'into':self.sql_into_log}
|
sqllogs = {'from':self.sql_from_log, 'into':self.sql_into_log}
|
||||||
sum = 0
|
sum = 0
|
||||||
|
|
|
@ -66,7 +66,7 @@ class configmanager(object):
|
||||||
'import_partial': "",
|
'import_partial': "",
|
||||||
'pidfile': None,
|
'pidfile': None,
|
||||||
'logfile': None,
|
'logfile': None,
|
||||||
'logrotate': '1',
|
'logrotate': '1',
|
||||||
'smtp_server': 'localhost',
|
'smtp_server': 'localhost',
|
||||||
'smtp_user': False,
|
'smtp_user': False,
|
||||||
'smtp_port':25,
|
'smtp_port':25,
|
||||||
|
@ -82,8 +82,8 @@ class configmanager(object):
|
||||||
'login_message': False,
|
'login_message': False,
|
||||||
'list_db' : True,
|
'list_db' : True,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.misc = {}
|
self.misc = {}
|
||||||
|
|
||||||
hasSSL = check_ssl()
|
hasSSL = check_ssl()
|
||||||
|
|
||||||
|
@ -135,7 +135,7 @@ class configmanager(object):
|
||||||
group = optparse.OptionGroup(parser, "Logging Configuration")
|
group = optparse.OptionGroup(parser, "Logging Configuration")
|
||||||
group.add_option("--logfile", dest="logfile", help="file where the server log will be stored")
|
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",
|
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",
|
group.add_option("--syslog", action="store_true", dest="syslog",
|
||||||
default=False, help="Send the log to the syslog server")
|
default=False, help="Send the log to the syslog server")
|
||||||
group.add_option('--log-level', dest='log_level', type='choice', choices=self._LOGLEVELS.keys(),
|
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',
|
'db_port', 'list_db', 'logfile', 'pidfile', 'smtp_port', 'cache_timeout',
|
||||||
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
|
'email_from', 'smtp_server', 'smtp_user', 'smtp_password', 'price_accuracy',
|
||||||
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
|
'netinterface', 'netport', 'db_maxconn', 'import_partial', 'addons_path',
|
||||||
'netrpc', 'xmlrpc', 'syslog', 'without_demo']
|
'netrpc', 'xmlrpc', 'syslog', 'without_demo']
|
||||||
|
|
||||||
if hasSSL:
|
if hasSSL:
|
||||||
keys.extend(['smtp_ssl', 'secure_cert_file', 'secure_pkey_file'])
|
keys.extend(['smtp_ssl', 'secure_cert_file', 'secure_pkey_file'])
|
||||||
|
@ -341,18 +341,18 @@ class configmanager(object):
|
||||||
if value=='False' or value=='false':
|
if value=='False' or value=='false':
|
||||||
value = False
|
value = False
|
||||||
self.options[name] = value
|
self.options[name] = value
|
||||||
#parse the other sections, as well
|
#parse the other sections, as well
|
||||||
for sec in p.sections():
|
for sec in p.sections():
|
||||||
if sec == 'options':
|
if sec == 'options':
|
||||||
continue
|
continue
|
||||||
if not self.misc.has_key(sec):
|
if not self.misc.has_key(sec):
|
||||||
self.misc[sec]= {}
|
self.misc[sec]= {}
|
||||||
for (name, value) in p.items(sec):
|
for (name, value) in p.items(sec):
|
||||||
if value=='True' or value=='true':
|
if value=='True' or value=='true':
|
||||||
value = True
|
value = True
|
||||||
if value=='False' or value=='false':
|
if value=='False' or value=='false':
|
||||||
value = False
|
value = False
|
||||||
self.misc[sec][name] = value
|
self.misc[sec][name] = value
|
||||||
except IOError:
|
except IOError:
|
||||||
pass
|
pass
|
||||||
except ConfigParser.NoSectionError:
|
except ConfigParser.NoSectionError:
|
||||||
|
@ -369,10 +369,10 @@ class configmanager(object):
|
||||||
p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt]))
|
p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt]))
|
||||||
else:
|
else:
|
||||||
p.set('options', opt, self.options[opt])
|
p.set('options', opt, self.options[opt])
|
||||||
|
|
||||||
for sec in self.misc.keys():
|
for sec in self.misc.keys():
|
||||||
for opt in self.misc[sec].keys():
|
for opt in self.misc[sec].keys():
|
||||||
p.set(sec,opt,self.misc[sec][opt])
|
p.set(sec,opt,self.misc[sec][opt])
|
||||||
|
|
||||||
# try to create the directories and write the file
|
# try to create the directories and write the file
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -386,15 +386,15 @@ def email_send(email_from, email_to, subject, body, email_cc=None, email_bcc=Non
|
||||||
smtp_server = config['smtp_server']
|
smtp_server = config['smtp_server']
|
||||||
if smtp_server.startswith('maildir:/'):
|
if smtp_server.startswith('maildir:/'):
|
||||||
from mailbox import Maildir
|
from mailbox import Maildir
|
||||||
maildir_path = smtp_server[8:]
|
maildir_path = smtp_server[8:]
|
||||||
try:
|
try:
|
||||||
mdir = Maildir(maildir_path,factory=None, create = True)
|
mdir = Maildir(maildir_path,factory=None, create = True)
|
||||||
mdir.add(msg.as_string(True))
|
mdir.add(msg.as_string(True))
|
||||||
return True
|
return True
|
||||||
except Exception,e:
|
except Exception,e:
|
||||||
netsvc.Logger().notifyChannel('email_send (maildir)', netsvc.LOG_ERROR, e)
|
netsvc.Logger().notifyChannel('email_send (maildir)', netsvc.LOG_ERROR, e)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
oldstderr = smtplib.stderr
|
oldstderr = smtplib.stderr
|
||||||
s = smtplib.SMTP()
|
s = smtplib.SMTP()
|
||||||
|
|
|
@ -29,38 +29,38 @@ __export_bis = {}
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
def __init_ebis():
|
def __init_ebis():
|
||||||
global __export_bis
|
global __export_bis
|
||||||
|
|
||||||
_evars = [ 'abs', 'all', 'any', 'basestring' , 'bool',
|
_evars = [ 'abs', 'all', 'any', 'basestring' , 'bool',
|
||||||
'chr', 'cmp','complex', 'dict', 'divmod', 'enumerate',
|
'chr', 'cmp','complex', 'dict', 'divmod', 'enumerate',
|
||||||
'float', 'frozenset', 'getattr', 'hasattr', 'hash',
|
'float', 'frozenset', 'getattr', 'hasattr', 'hash',
|
||||||
'hex', 'id','int', 'iter', 'len', 'list', 'long', 'map', 'max',
|
'hex', 'id','int', 'iter', 'len', 'list', 'long', 'map', 'max',
|
||||||
'min', 'oct', 'ord','pow', 'range', 'reduce', 'repr',
|
'min', 'oct', 'ord','pow', 'range', 'reduce', 'repr',
|
||||||
'reversed', 'round', 'set', 'setattr', 'slice','sorted', 'str',
|
'reversed', 'round', 'set', 'setattr', 'slice','sorted', 'str',
|
||||||
'sum', 'tuple','type', 'unichr','unicode', 'xrange',
|
'sum', 'tuple','type', 'unichr','unicode', 'xrange',
|
||||||
'True','False', 'None', 'NotImplemented', 'Ellipsis', ]
|
'True','False', 'None', 'NotImplemented', 'Ellipsis', ]
|
||||||
|
|
||||||
if sys.version_info[0:2] >= (2,6):
|
if sys.version_info[0:2] >= (2,6):
|
||||||
_evars.extend(['bin', 'format', 'next'])
|
_evars.extend(['bin', 'format', 'next'])
|
||||||
for v in _evars:
|
for v in _evars:
|
||||||
__export_bis[v] = __builtins__[v]
|
__export_bis[v] = __builtins__[v]
|
||||||
|
|
||||||
|
|
||||||
__init_ebis()
|
__init_ebis()
|
||||||
|
|
||||||
|
|
||||||
def safe_eval(expr,sglobals,slocals = None):
|
def safe_eval(expr,sglobals,slocals = None):
|
||||||
""" A little safer version of eval().
|
""" A little safer version of eval().
|
||||||
This one, will use fewer builtin functions, so that only
|
This one, will use fewer builtin functions, so that only
|
||||||
arithmetic and logic expressions can really work """
|
arithmetic and logic expressions can really work """
|
||||||
|
|
||||||
global __export_bis
|
global __export_bis
|
||||||
|
|
||||||
if not sglobals.has_key('__builtins__'):
|
if not sglobals.has_key('__builtins__'):
|
||||||
# we copy, because we wouldn't want successive calls to safe_eval
|
# we copy, because we wouldn't want successive calls to safe_eval
|
||||||
# to be able to alter the builtins.
|
# to be able to alter the builtins.
|
||||||
sglobals['__builtins__'] = __export_bis.copy()
|
sglobals['__builtins__'] = __export_bis.copy()
|
||||||
|
|
||||||
return eval(expr,sglobals,slocals)
|
return eval(expr,sglobals,slocals)
|
||||||
|
|
||||||
#eof
|
#eof
|
||||||
|
|
|
@ -133,12 +133,12 @@ class GettextAlias(object):
|
||||||
return source
|
return source
|
||||||
|
|
||||||
cr = frame.f_locals.get('cr')
|
cr = frame.f_locals.get('cr')
|
||||||
try:
|
try:
|
||||||
lang = (frame.f_locals.get('context') or {}).get('lang', False)
|
lang = (frame.f_locals.get('context') or {}).get('lang', False)
|
||||||
if not (lang and cr):
|
if not (lang and cr):
|
||||||
return source
|
return source
|
||||||
except:
|
except:
|
||||||
return source
|
return source
|
||||||
|
|
||||||
cr.execute('select value from ir_translation where lang=%s and type=%s and src=%s', (lang, 'code', source))
|
cr.execute('select value from ir_translation where lang=%s and type=%s and src=%s', (lang, 'code', source))
|
||||||
res_trans = cr.fetchone()
|
res_trans = cr.fetchone()
|
||||||
|
@ -154,7 +154,7 @@ class TinyPoFile(object):
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
self.buffer.seek(0)
|
self.buffer.seek(0)
|
||||||
self.lines = self._get_lines()
|
self.lines = self._get_lines()
|
||||||
self.lines_count = len(self.lines);
|
self.lines_count = len(self.lines);
|
||||||
|
|
||||||
self.first = True
|
self.first = True
|
||||||
self.tnrs= []
|
self.tnrs= []
|
||||||
|
@ -170,7 +170,7 @@ class TinyPoFile(object):
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def cur_line(self):
|
def cur_line(self):
|
||||||
return (self.lines_count - len(self.lines))
|
return (self.lines_count - len(self.lines))
|
||||||
|
|
||||||
def next(self):
|
def next(self):
|
||||||
def unquote(str):
|
def unquote(str):
|
||||||
|
@ -185,30 +185,30 @@ class TinyPoFile(object):
|
||||||
else:
|
else:
|
||||||
tmp_tnrs = []
|
tmp_tnrs = []
|
||||||
line = None
|
line = None
|
||||||
fuzzy = False
|
fuzzy = False
|
||||||
while (not line):
|
while (not line):
|
||||||
if 0 == len(self.lines):
|
if 0 == len(self.lines):
|
||||||
raise StopIteration()
|
raise StopIteration()
|
||||||
line = self.lines.pop(0).strip()
|
line = self.lines.pop(0).strip()
|
||||||
if line.startswith('#:'):
|
if line.startswith('#:'):
|
||||||
if ' ' in line[2:].strip():
|
if ' ' in line[2:].strip():
|
||||||
for lpart in line[2:].strip().split(' '):
|
for lpart in line[2:].strip().split(' '):
|
||||||
tmp_tnrs.append(lpart.strip().split(':',2))
|
tmp_tnrs.append(lpart.strip().split(':',2))
|
||||||
else:
|
else:
|
||||||
tmp_tnrs.append( line[2:].strip().split(':',2) )
|
tmp_tnrs.append( line[2:].strip().split(':',2) )
|
||||||
elif line.startswith('#,') and (line[2:].strip() == 'fuzzy'):
|
elif line.startswith('#,') and (line[2:].strip() == 'fuzzy'):
|
||||||
fuzzy = True
|
fuzzy = True
|
||||||
line = self.lines.pop(0).strip()
|
line = self.lines.pop(0).strip()
|
||||||
while not line:
|
while not line:
|
||||||
# allow empty lines between comments and msgid
|
# allow empty lines between comments and msgid
|
||||||
line = self.lines.pop(0).strip()
|
line = self.lines.pop(0).strip()
|
||||||
if line.startswith('#~ '):
|
if line.startswith('#~ '):
|
||||||
while line.startswith('#~ ') or not line.strip():
|
while line.startswith('#~ ') or not line.strip():
|
||||||
if 0 == len(self.lines):
|
if 0 == len(self.lines):
|
||||||
raise StopIteration()
|
raise StopIteration()
|
||||||
line = self.lines.pop(0)
|
line = self.lines.pop(0)
|
||||||
# This has been a deprecated entry, don't return anything
|
# This has been a deprecated entry, don't return anything
|
||||||
return self.next()
|
return self.next()
|
||||||
|
|
||||||
|
|
||||||
if not line.startswith('msgid'):
|
if not line.startswith('msgid'):
|
||||||
|
@ -242,9 +242,9 @@ class TinyPoFile(object):
|
||||||
self.tnrs.append((t, n, r, source, trad))
|
self.tnrs.append((t, n, r, source, trad))
|
||||||
|
|
||||||
self.first = False
|
self.first = False
|
||||||
|
|
||||||
if name == None:
|
if name == None:
|
||||||
return self.next()
|
return self.next()
|
||||||
return type, name, res_id, source, trad
|
return type, name, res_id, source, trad
|
||||||
|
|
||||||
def write_infos(self, modules):
|
def write_infos(self, modules):
|
||||||
|
@ -279,7 +279,7 @@ class TinyPoFile(object):
|
||||||
def quote(s):
|
def quote(s):
|
||||||
return '"%s"' % s.replace('"','\\"') \
|
return '"%s"' % s.replace('"','\\"') \
|
||||||
.replace('\n', '\\n"\n"') \
|
.replace('\n', '\\n"\n"') \
|
||||||
.replace(' \\ ',' \\\\ ')
|
.replace(' \\ ',' \\\\ ')
|
||||||
|
|
||||||
|
|
||||||
plurial = len(modules) > 1 and 's' or ''
|
plurial = len(modules) > 1 and 's' or ''
|
||||||
|
@ -490,9 +490,9 @@ def trans_generate(lang, modules, dbname=None):
|
||||||
}
|
}
|
||||||
|
|
||||||
# export fields
|
# export fields
|
||||||
if not result.has_key('fields'):
|
if not result.has_key('fields'):
|
||||||
logger.notifyChannel("db",netsvc.LOG_WARNING,"res has no fields: %r" % result)
|
logger.notifyChannel("db",netsvc.LOG_WARNING,"res has no fields: %r" % result)
|
||||||
continue
|
continue
|
||||||
for field_name, field_def in result['fields'].iteritems():
|
for field_name, field_def in result['fields'].iteritems():
|
||||||
res_name = name + ',' + field_name
|
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)
|
push_translation(module, 'wizard_button', res_name, 0, button_label)
|
||||||
|
|
||||||
elif model=='ir.model.fields':
|
elif model=='ir.model.fields':
|
||||||
try:
|
try:
|
||||||
field_name = encode(obj.name)
|
field_name = encode(obj.name)
|
||||||
except AttributeError, exc:
|
except AttributeError, exc:
|
||||||
logger.notifyChannel("db", netsvc.LOG_ERROR, "name error in %s: %s" % (xml_name,str(exc)))
|
logger.notifyChannel("db", netsvc.LOG_ERROR, "name error in %s: %s" % (xml_name,str(exc)))
|
||||||
continue
|
continue
|
||||||
objmodel = pool.get(obj.model)
|
objmodel = pool.get(obj.model)
|
||||||
if not objmodel or not field_name in objmodel._columns:
|
if not objmodel or not field_name in objmodel._columns:
|
||||||
continue
|
continue
|
||||||
|
@ -578,28 +578,28 @@ def trans_generate(lang, modules, dbname=None):
|
||||||
for field_name,field_def in pool.get(model)._columns.items():
|
for field_name,field_def in pool.get(model)._columns.items():
|
||||||
if field_def.translate:
|
if field_def.translate:
|
||||||
name = model + "," + field_name
|
name = model + "," + field_name
|
||||||
try:
|
try:
|
||||||
trad = getattr(obj, field_name) or ''
|
trad = getattr(obj, field_name) or ''
|
||||||
except:
|
except:
|
||||||
trad = ''
|
trad = ''
|
||||||
push_translation(module, 'model', name, xml_name, encode(trad))
|
push_translation(module, 'model', name, xml_name, encode(trad))
|
||||||
|
|
||||||
# parse source code for _() calls
|
# parse source code for _() calls
|
||||||
def get_module_from_path(path,mod_paths=None):
|
def get_module_from_path(path,mod_paths=None):
|
||||||
if not mod_paths:
|
if not mod_paths:
|
||||||
# First, construct a list of possible 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)
|
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(','))
|
ad_paths= map(lambda m: os.path.abspath(m.strip()),tools.config['addons_path'].split(','))
|
||||||
mod_paths=[def_path]
|
mod_paths=[def_path]
|
||||||
for adp in ad_paths:
|
for adp in ad_paths:
|
||||||
mod_paths.append(adp)
|
mod_paths.append(adp)
|
||||||
if not adp.startswith('/'):
|
if not adp.startswith('/'):
|
||||||
mod_paths.append(os.path.join(def_path,adp))
|
mod_paths.append(os.path.join(def_path,adp))
|
||||||
elif adp.startswith(def_path):
|
elif adp.startswith(def_path):
|
||||||
mod_paths.append(adp[len(def_path)+1:])
|
mod_paths.append(adp[len(def_path)+1:])
|
||||||
|
|
||||||
for mp in mod_paths:
|
for mp in mod_paths:
|
||||||
if path.startswith(mp) and (os.path.dirname(path) != mp):
|
if path.startswith(mp) and (os.path.dirname(path) != mp):
|
||||||
path = path[len(mp)+1:]
|
path = path[len(mp)+1:]
|
||||||
return path.split(os.path.sep)[0]
|
return path.split(os.path.sep)[0]
|
||||||
return 'base' # files that are not in a module are considered as being in 'base' module
|
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,
|
# if the resource id (res_id) is in that list, use it,
|
||||||
# otherwise use the whole list
|
# otherwise use the whole list
|
||||||
if not ids:
|
if not ids:
|
||||||
ids = []
|
ids = []
|
||||||
ids = (dic['res_id'] in ids) and [dic['res_id']] or ids
|
ids = (dic['res_id'] in ids) and [dic['res_id']] or ids
|
||||||
for id in ids:
|
for id in ids:
|
||||||
dic['res_id'] = id
|
dic['res_id'] = id
|
||||||
|
|
Loading…
Reference in New Issue