bzr revid: olt@tinyerp.com-20080812144456-xvh2y1ybziok9twi
This commit is contained in:
Olivier Laurent 2008-08-12 16:44:56 +02:00
parent 4c2a727132
commit cc5a062faf
7 changed files with 2792 additions and 720 deletions

View File

@ -42,14 +42,17 @@ _group={}
_res_id = 1
_res = {}
class ServiceEndPointCall(object):
def __init__(self, id, method):
self._id = id
self._meth = method
def __call__(self, *args):
_res[self._id] = self._meth(*args)
return self._id
class ServiceEndPoint(object):
def __init__(self, name, id):
self._id = id
@ -57,11 +60,14 @@ class ServiceEndPoint(object):
s = _service[name]
for m in s._method:
self._meth[m] = s._method[m]
def __getattr__(self, name):
return ServiceEndPointCall(self._id, self._meth[name])
class Service(object):
_serviceEndPointID = 0
def __init__(self, name, audience=''):
_service[name] = self
self.__name = name
@ -118,6 +124,7 @@ class Service(object):
def currentFailure(self, s):
pass
class LocalService(Service):
def __init__(self, name):
self.__name = name
@ -126,12 +133,15 @@ class LocalService(Service):
for m in s._method:
setattr(self, m, s._method[m])
class ServiceUnavailable(Exception):
pass
def service_exist(name):
return (name in _service) and bool(_service[name])
def get_rpc_paths():
return map(lambda s: '/xmlrpc/%s' % s, _service)
@ -141,6 +151,7 @@ LOG_WARNING='warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'
def init_logger():
from tools import config
import os
@ -179,6 +190,7 @@ class Logger(object):
log = logging.getLogger(name)
getattr(log, level)(msg)
class Agent(object):
_timers = []
_logger = Logger()
@ -203,23 +215,29 @@ class Agent(object):
timer.cancel()
quit = classmethod(quit)
class RpcGateway(object):
def __init__(self, name):
self.name = name
class Dispatcher(object):
def __init__(self):
pass
def monitor(self, signal):
pass
def run(self):
pass
class xmlrpc(object):
class RpcGateway(object):
def __init__(self, name):
self.name = name
class GenericXMLRPCRequestHandler:
def _dispatch(self, method, params):
import traceback
@ -244,10 +262,12 @@ class GenericXMLRPCRequestHandler:
pdb.post_mortem(tb)
raise xmlrpclib.Fault(s, tb_s)
class SimpleXMLRPCRequestHandler(GenericXMLRPCRequestHandler,
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler):
SimpleXMLRPCServer.SimpleXMLRPCRequestHandler.rpc_paths = get_rpc_paths()
class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn,
SimpleXMLRPCServer.SimpleXMLRPCServer):
@ -256,6 +276,7 @@ class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn,
socket.SO_REUSEADDR, 1)
SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
class HttpDaemon(threading.Thread):
def __init__(self, interface, port, secure=False):
@ -287,7 +308,7 @@ class HttpDaemon(threading.Thread):
def stop(self):
self.running = False
if os.name <> 'nt':
if os.name != 'nt':
if hasattr(socket, 'SHUT_RDWR'):
if self.secure:
self.server.socket.sock_shutdown(socket.SHUT_RDWR)
@ -368,6 +389,7 @@ class TinySocketClientThread(threading.Thread):
def stop(self):
self.running = False
class TinySocketServerThread(threading.Thread):
def __init__(self, interface, port, secure=False):
threading.Thread.__init__(self)

View File

@ -3,6 +3,7 @@
from tools import flatten
class expression(object):
"""
parse a domain expression
@ -103,7 +104,7 @@ class expression(object):
if isinstance(self.__right, list):
self.__right = tuple(self.__right)
elif exp and not self._is_expression(self.__exp):
raise ValueError, 'Bad expression: %r' % (self.__exp,)
raise ValueError('Bad expression: %r' % (self.__exp,))
def parse(self, cr, uid, table, context):
@ -202,7 +203,7 @@ class expression(object):
ids2 = list(self.__right)
self.__operator = 'in'
if field._obj <> self.__table._name:
if field._obj != self.__table._name:
self.__right = ids2 + _rec_get(ids2, field_obj, self.__table._parent_name)
else:
self.__right = ids2 + _rec_get(ids2, self.__table, self.__left)
@ -264,7 +265,7 @@ class expression(object):
del params[i]
len_after = len(params)
check_nulls = len_after <> len_before
check_nulls = len_after != len_before
query = '(1=0)'
if len_after:

View File

@ -49,6 +49,7 @@ import warnings
import tools
def _symbol_set(symb):
if symb == None or symb == False:
return None
@ -56,6 +57,7 @@ def _symbol_set(symb):
return symb.encode('utf-8')
return str(symb)
class _column(object):
_classic_read = True
_classic_write = True
@ -97,20 +99,24 @@ class _column(object):
def set(self, cr, obj, id, name, value, user=None, context=None):
cr.execute('update '+obj._table+' set '+name+'='+self._symbol_set[0]+' where id=%d', (self._symbol_set[1](value), id))
def set_memory(self, cr, obj, id, name, value, user=None, context=None):
raise Exception, _('Not implemented set_memory method !')
raise Exception(_('Not implemented set_memory method !'))
def get_memory(self, cr, obj, ids, name, context=None, values=None):
raise Exception, _('Not implemented get_memory method !')
raise Exception(_('Not implemented get_memory method !'))
def get(self, cr, obj, ids, name, context=None, values=None):
raise Exception, _('undefined get method !')
raise Exception(_('undefined get method !'))
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
ids = obj.search(cr, uid, args+self._domain+[(name, 'ilike', value)], offset, limit)
res = obj.read(cr, uid, ids, [name])
return [x[name] for x in res]
def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, context=None):
raise Exception, _('Not implemented search_memory method !')
raise Exception(_('Not implemented search_memory method !'))
# ---------------------------------------------------------
# Simple fields
@ -121,17 +127,21 @@ class boolean(_column):
_symbol_f = lambda x: x and 'True' or 'False'
_symbol_set = (_symbol_c, _symbol_f)
class integer(_column):
_type = 'integer'
_symbol_c = '%d'
_symbol_f = lambda x: int(x or 0)
_symbol_set = (_symbol_c, _symbol_f)
class reference(_column):
_type = 'reference'
def __init__(self, string, selection, size, **args):
_column.__init__(self, string=string, size=size, selection=selection, **args)
class char(_column):
_type = 'char'
@ -158,35 +168,43 @@ class char(_column):
u_symb = unicode(symb)
return u_symb.encode('utf8')[:self.size]
class text(_column):
_type = 'text'
import __builtin__
class float(_column):
_type = 'float'
_symbol_c = '%f'
_symbol_f = lambda x: __builtin__.float(x or 0.0)
_symbol_set = (_symbol_c, _symbol_f)
def __init__(self, string='unknown', digits=None, **args):
_column.__init__(self, string=string, **args)
self.digits = digits
class date(_column):
_type = 'date'
class datetime(_column):
_type = 'datetime'
class time(_column):
_type = 'time'
class binary(_column):
_type = 'binary'
_symbol_c = '%s'
_symbol_f = lambda symb: symb and psycopg.Binary(symb) or None
_symbol_set = (_symbol_c, _symbol_f)
class selection(_column):
_type = 'selection'
@ -233,6 +251,7 @@ class one2one(_column):
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name', 'like', value)], offset, limit)
class many2one(_column):
_classic_read = False
_classic_write = True
@ -309,6 +328,7 @@ class many2one(_column):
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name', 'like', value)], offset, limit)
class one2many(_column):
_classic_read = False
_classic_write = False
@ -365,7 +385,6 @@ class one2many(_column):
def search_memory(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like', context=None):
raise _('Not Implemented')
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if not context:
context = {}
@ -408,9 +427,11 @@ class one2many(_column):
cr.execute('update '+_table+' set '+self._fields_id+'=NULL where '+self._fields_id+'=%d and id not in ('+','.join(map(str, ids2))+')', (id,))
if act[2]:
cr.execute('update '+_table+' set '+self._fields_id+'=%d where id in ('+','.join(map(str, act[2]))+')', (id,))
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
return obj.pool.get(self._obj).name_search(cr, uid, value, self._domain, offset, limit)
#
# Values: (0, 0, { fields }) create
# (1, ID, { fields }) modification
@ -527,7 +548,6 @@ class many2many(_column):
# ---------------------------------------------------------
# Function fields
# ---------------------------------------------------------
class function(_column):
_classic_read = False
_classic_write = False
@ -579,6 +599,7 @@ class function(_column):
if self._fnct_inv:
self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
# ---------------------------------------------------------
# Serialized fields
# ---------------------------------------------------------

View File

@ -49,21 +49,18 @@
import time
import types
from xml import dom, xpath
from xml.parsers import expat
import string
import pooler
import psycopg
import netsvc
import re
import fields
import ir
import tools
from tools.config import config
regex_order = re.compile('^([a-zA-Z0-9_]+( desc)?( asc)?,?)+$', re.I)
def intersect(la, lb):
return filter(lambda x: x in lb, la)
@ -74,6 +71,7 @@ class except_orm(Exception):
self.value = value
self.args = (name, value)
# Readonly python database object browser
class browse_null(object):
@ -92,6 +90,7 @@ class browse_null(object):
def __nonzero__(self):
return False
#
# TODO: execute an object method on browse_record_list
#
@ -131,7 +130,7 @@ class browse_record(object):
def __getitem__(self, name):
if name == 'id':
return self._id
if not self._data[self._id].has_key(name):
if not name in self._data[self._id]:
# build the list of fields we will fetch
# fetch the definition of the field which was asked for
@ -160,7 +159,7 @@ class browse_record(object):
# otherwise we fetch only that field
else:
ffields = [(name, col)]
ids = filter(lambda id: not self._data[id].has_key(name), self._data.keys())
ids = filter(lambda id: not name in self._data[id], self._data.keys())
# read the data
fffields = map(lambda x: x[0], ffields)
datas = self._table.read(self._cr, self._uid, ids, fffields, context=self._context, load="_classic_write")
@ -243,7 +242,7 @@ def get_pg_type(f):
fields.binary: 'bytea',
fields.many2one: 'int4',
}
if type_dict.has_key(type(f)):
if type(f) in type_dict:
f_type = (type_dict[type(f)], type_dict[type(f)])
elif isinstance(f, fields.float):
if f.digits:
@ -264,7 +263,7 @@ def get_pg_type(f):
f_type = ('int4', 'INTEGER')
else:
f_type = ('varchar', 'VARCHAR(%d)' % f_size)
elif isinstance(f, fields.function) and type_dict.has_key(eval('fields.'+(f._type))):
elif isinstance(f, fields.function) and eval('fields.'+(f._type)) in type_dict:
t = eval('fields.'+(f._type))
f_type = (type_dict[t], type_dict[t])
elif isinstance(f, fields.function) and f._type == 'float':
@ -277,6 +276,7 @@ def get_pg_type(f):
f_type = None
return f_type
class orm_template(object):
_name = None
_columns = {}
@ -345,7 +345,7 @@ class orm_template(object):
)
else:
for key, val in vals.items():
if cols[k][key]<>vals[key]:
if cols[k][key] != vals[key]:
print 'Different', cols[k][key], vals[key], k, key, self._name
cr.execute('update ir_model_fields set field_description=%s where model=%s and name=%s', (vals['field_description'], vals['model'], vals['name']))
cr.commit()
@ -436,6 +436,7 @@ class orm_template(object):
context = {}
fields = map(lambda x: x.split('/'), fields)
logger = netsvc.Logger()
def process_liness(self, datas, prefix, fields_def, position=0):
line = datas[position]
row = {}
@ -448,7 +449,7 @@ class orm_template(object):
#
for i in range(len(fields)):
if i >= len(line):
raise Exception, _('Please check that all your lines have %d columns.') % (len(fields),)
raise Exception(_('Please check that all your lines have %d columns.') % (len(fields),))
field = fields[i]
if field == ["id"]:
data_id = line[i]
@ -762,7 +763,7 @@ class orm_template(object):
groups = None
group_str = node.getAttribute('groups')
if ',' in group_str:
groups = group_str.split(',');
groups = group_str.split(',')
readonly = False
access_pool = self.pool.get('ir.model.access')
for group in groups:
@ -849,7 +850,6 @@ class orm_template(object):
fields[field].update(fields_def[field])
return arch, fields
def __get_default_calendar_view(self):
"""Generate a default calendar view (For internal use only).
"""
@ -907,7 +907,8 @@ class orm_template(object):
return node
for child in node.childNodes:
res = _find(child, node2)
if res: return res
if res:
return res
return None
doc_src = dom.minidom.parseString(src)
@ -945,7 +946,7 @@ class orm_template(object):
elif pos=='before':
node.parentNode.insertBefore(child, node)
else:
raise AttributeError, _('Unknown position in inherited view %s !') % pos
raise AttributeError(_('Unknown position in inherited view %s !') % pos)
else:
attrs = ''.join([
' %s="%s"' % (attr, node2.getAttribute(attr))
@ -953,7 +954,7 @@ class orm_template(object):
if attr != 'position'
])
tag = "<%s%s>" % (node2.localName, attrs)
raise AttributeError, _("Couldn't find tag '%s' in parent view !") % tag
raise AttributeError(_("Couldn't find tag '%s' in parent view !") % tag)
return doc_src.toxml(encoding="utf-8").replace('\t', '')
result = {'type': view_type, 'model': self._name}
@ -1081,12 +1082,14 @@ class orm_template(object):
def copy(self, cr, uid, id, default=None, context=None):
raise _('The copy method is not implemented on this object !')
class orm_memory(orm_template):
_protected = ['read', 'write', 'create', 'default_get', 'perm_read', 'unlink', 'fields_get', 'fields_view_get', 'search', 'name_get', 'distinct_field_get', 'name_search', 'copy', 'import_data', 'search_count']
_inherit_fields = {}
_max_count = 200
_max_hours = 1
_check_time = 20
def __init__(self, cr):
super(orm_memory, self).__init__(cr)
self.datas = {}
@ -1354,7 +1357,7 @@ class orm(orm_template):
except AttributeError:
ref = f._obj.replace('.', '_')
# ir_actions is inherited so foreign key doesn't work on it
if ref <> 'ir_actions':
if ref != 'ir_actions':
cr.execute("ALTER TABLE \"%s\" ADD FOREIGN KEY (\"%s\") REFERENCES \"%s\" ON DELETE %s" % (self._table, k, ref, f.ondelete))
if f.select:
cr.execute("CREATE INDEX \"%s_%s_index\" ON \"%s\" (\"%s\")" % (self._table, k, self._table, k))
@ -1396,7 +1399,7 @@ class orm(orm_template):
# if the field is required and hasn't got a NOT NULL constraint
if f.required and f_pg_notnull == 0:
# set the field to the default value if any
if self._defaults.has_key(k):
if k in self._defaults:
default = self._defaults[k](self, cr, 1, {})
if not (default is False):
cr.execute("UPDATE \"%s\" SET \"%s\"='%s' WHERE %s is NULL" % (self._table, k, default, k))
@ -2010,7 +2013,7 @@ class orm(orm_template):
self._validate(cr, user, ids, context)
if context.has_key('read_delta'):
if 'read_delta' in context:
del context['read_delta']
wf_service = netsvc.LocalService("workflow")

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@ import netsvc
db_dic = {}
pool_dic = {}
def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False):
if not status:
status={}
@ -60,11 +61,13 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False)
pool.get('ir.cron')._poolJobs(db.dbname)
return db, pool
def restart_pool(db_name, force_demo=False, update_module=False):
# del db_dic[db_name]
del pool_dic[db_name]
return get_db_and_pool(db_name, force_demo, update_module=update_module)
def close_db(db_name):
if db_name in db_dic:
db_dic[db_name].truedb.close()
@ -72,6 +75,7 @@ def close_db(db_name):
if db_name in pool_dic:
del pool_dic[db_name]
def get_db_only(db_name):
if db_name in db_dic:
db = db_dic[db_name]
@ -80,10 +84,12 @@ def get_db_only(db_name):
db_dic[db_name] = db
return db
def get_db(db_name):
# print "get_db", db_name
return get_db_and_pool(db_name)[0]
def get_pool(db_name, force_demo=False, status=None, update_module=False):
# print "get_pool", db_name
pool = get_db_and_pool(db_name, force_demo, status, update_module)[1]
@ -94,6 +100,7 @@ def get_pool(db_name, force_demo=False, status=None, update_module=False):
return pool
# return get_db_and_pool(db_name)[1]
def init():
global db
# db = get_db_only(tools.config['db_name'])

View File

@ -246,6 +246,7 @@ if tools.config['netrpc']:
tinySocket = netsvc.TinySocketServerThread(netinterface, netport, False)
logger.notifyChannel("web-services", netsvc.LOG_INFO, "starting netrpc service, port "+str(netport))
def handler(signum, frame):
from tools import config
if tools.config['netrpc']: