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

@ -31,56 +31,62 @@
import time
import threading
import SimpleXMLRPCServer,signal,sys,xmlrpclib
import SimpleXMLRPCServer, signal, sys, xmlrpclib
import SocketServer
import socket
import logging
import os
_service={}
_group={}
_res_id=1
_res={}
_service = {}
_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)
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
self._meth={}
s=_service[name]
self._meth = {}
s = _service[name]
for m in s._method:
self._meth[m]=s._method[m]
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
self._method={}
self.exportedMethods=None
self._response_process=None
self._response_process_id=None
self._response=None
def joinGroup(self,name):
def __init__(self, name, audience=''):
_service[name] = self
self.__name = name
self._method = {}
self.exportedMethods = None
self._response_process = None
self._response_process_id = None
self._response = None
def joinGroup(self, name):
if not name in _group:
_group[name]={}
_group[name][self.__name]=self
_group[name] = {}
_group[name][self.__name] = self
def exportMethod(self, m):
if callable(m):
self._method[m.__name__]=m
self._method[m.__name__] = m
def serviceEndPoint(self,s):
def serviceEndPoint(self, s):
if Service._serviceEndPointID >= 2**16:
Service._serviceEndPointID = 0
Service._serviceEndPointID += 1
@ -89,57 +95,62 @@ class Service(object):
def conversationId(self):
return 1
def processResponse(self,s,id):
def processResponse(self, s, id):
self._response_process, self._response_process_id = s, id
def processFailure(self,s,id):
def processFailure(self, s, id):
pass
def resumeResponse(self,s):
def resumeResponse(self, s):
pass
def cancelResponse(self,s):
def cancelResponse(self, s):
pass
def suspendResponse(self,s):
def suspendResponse(self, s):
if self._response_process:
self._response_process(self._response_process_id,
_res[self._response_process_id])
self._response_process=None
self._response=s(self._response_process_id)
self._response_process = None
self._response = s(self._response_process_id)
def abortResponse(self, error, description, origin, details):
import tools
if not tools.config['debug_mode']:
raise Exception("%s -- %s\n\n%s"%(origin,description,details))
raise Exception("%s -- %s\n\n%s"%(origin, description, details))
else:
raise
def currentFailure(self,s):
def currentFailure(self, s):
pass
class LocalService(Service):
def __init__(self, name):
self.__name=name
s=_service[name]
self._service=s
self.__name = name
s = _service[name]
self._service = s
for m in s._method:
setattr(self,m,s._method[m])
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)
LOG_DEBUG='debug'
LOG_INFO='info'
LOG_WARNING='warn'
LOG_ERROR='error'
LOG_CRITICAL='critical'
LOG_DEBUG = 'debug'
LOG_INFO = 'info'
LOG_WARNING = 'warn'
LOG_ERROR = 'error'
LOG_CRITICAL = 'critical'
def init_logger():
from tools import config
@ -175,9 +186,10 @@ def init_logger():
class Logger(object):
def notifyChannel(self,name,level,msg):
def notifyChannel(self, name, level, msg):
log = logging.getLogger(name)
getattr(log,level)(msg)
getattr(log, level)(msg)
class Agent(object):
_timers = []
@ -185,9 +197,9 @@ class Agent(object):
def setAlarm(self, fn, dt, args=None, kwargs=None):
if not args:
args=[]
args = []
if not kwargs:
kwargs={}
kwargs = {}
wait = dt - time.time()
if wait > 0:
self._logger.notifyChannel('timers', LOG_DEBUG, "Job scheduled in %s seconds for %s.%s" % (wait, fn.im_class.__name__, fn.func_name))
@ -201,42 +213,48 @@ class Agent(object):
def quit(cls):
for timer in cls._timers:
timer.cancel()
quit=classmethod(quit)
quit = classmethod(quit)
class RpcGateway(object):
def __init__(self, name):
self.name=name
self.name = name
class Dispatcher(object):
def __init__(self):
pass
def monitor(self,signal):
def monitor(self, signal):
pass
def run(self):
pass
class xmlrpc(object):
class RpcGateway(object):
def __init__(self, name):
self.name=name
self.name = name
class GenericXMLRPCRequestHandler:
def _dispatch(self, method, params):
import traceback
try:
n=self.path.split("/")[-1]
s=LocalService(n)
m=getattr(s,method)
s._service._response=None
r=m(*params)
res=s._service._response
if res!=None:
r=res
n = self.path.split("/")[-1]
s = LocalService(n)
m = getattr(s, method)
s._service._response = None
r = m(*params)
res = s._service._response
if res != None:
r = res
return r
except Exception, e:
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(
sys.exc_type, sys.exc_value, sys.exc_traceback))
s=str(e)
s = str(e)
import tools
if tools.config['debug_mode']:
import pdb
@ -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,12 +276,13 @@ class SimpleThreadedXMLRPCServer(SocketServer.ThreadingMixIn,
socket.SO_REUSEADDR, 1)
SimpleXMLRPCServer.SimpleXMLRPCServer.server_bind(self)
class HttpDaemon(threading.Thread):
def __init__(self, interface,port, secure=False):
def __init__(self, interface, port, secure=False):
threading.Thread.__init__(self)
self.__port=port
self.__interface=interface
self.__port = port
self.__interface = interface
self.secure = secure
if secure:
from ssl import SecureXMLRPCServer
@ -277,17 +298,17 @@ class HttpDaemon(threading.Thread):
SecureXMLRPCServer.SecureXMLRPCServer.server_bind(self)
self.server = SecureThreadedXMLRPCServer((interface, port),
SecureXMLRPCRequestHandler,0)
SecureXMLRPCRequestHandler, 0)
else:
self.server = SimpleThreadedXMLRPCServer((interface, port),
SimpleXMLRPCRequestHandler,0)
SimpleXMLRPCRequestHandler, 0)
def attach(self,path,gw):
def attach(self, path, gw):
pass
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)
@ -342,17 +363,17 @@ class TinySocketClientThread(threading.Thread):
self.threads.remove(self)
return False
try:
s=LocalService(msg[0])
m=getattr(s,msg[1])
s._service._response=None
r=m(*msg[2:])
res=s._service._response
if res!=None:
r=res
s = LocalService(msg[0])
m = getattr(s, msg[1])
s._service._response = None
r = m(*msg[2:])
res = s._service._response
if res != None:
r = res
ts.mysend(r)
except Exception, e:
tb_s = reduce(lambda x, y: x+y, traceback.format_exception(sys.exc_type, sys.exc_value, sys.exc_traceback))
s=str(e)
s = str(e)
import tools
if tools.config['debug_mode']:
import pdb
@ -368,11 +389,12 @@ 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)
self.__port=port
self.__interface=interface
self.__port = port
self.__interface = interface
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.socket.bind((self.__interface, self.__port))
@ -394,7 +416,7 @@ class TinySocketServerThread(threading.Thread):
return False
def stop(self):
self.running=False
self.running = False
for t in self.threads:
t.stop()
try:

View File

@ -3,6 +3,7 @@
from tools import flatten
class expression(object):
"""
parse a domain expression
@ -47,7 +48,7 @@ class expression(object):
def _is_operator(self, element):
return isinstance(element, str) \
and element in ['&','|']
and element in ['&', '|']
def _is_leaf(self, element):
return isinstance(element, tuple) \
@ -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):
@ -162,7 +163,7 @@ class expression(object):
self.__left, self.__right = None, None
self.__operator = '&'
self.__exp = ('&',) + tuple( [tuple(e.__exp) for e in self.__children] )
self.__exp = ('&',) + tuple([tuple(e.__exp) for e in self.__children])
elif field._type == 'one2many':
if isinstance(self.__right, basestring):
@ -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:
@ -323,14 +324,14 @@ class expression(object):
else:
children = [child.to_sql() for child in self.__children]
params = flatten([child[1] for child in children])
query = "( %s )" % (" %s " % {'&' : 'AND', '|' : 'OR' }[self.__operator]).join([child[0] for child in children if child[0]])
query = "( %s )" % (" %s " % {'&': 'AND', '|': 'OR'}[self.__operator]).join([child[0] for child in children if child[0]])
return (query, params)
def __get_tables(self):
return self.__tables + [child.__get_tables() for child in self.__children]
def get_tables(self):
return [ '"%s"' % t for t in set(flatten(self.__get_tables()))]
return ['"%s"' % t for t in set(flatten(self.__get_tables()))]
#def

View File

@ -49,13 +49,15 @@ import warnings
import tools
def _symbol_set(symb):
if symb==None or symb==False:
if symb == None or symb == False:
return None
elif isinstance(symb, unicode):
return symb.encode('utf-8')
return str(symb)
class _column(object):
_classic_read = True
_classic_write = True
@ -79,13 +81,13 @@ class _column(object):
self.ondelete = ondelete
self.translate = translate
self._domain = domain or []
self.relate =False
self.relate = False
self._context = context
self.group_name = False
self.write = False
self.read = False
self.view_load = 0
self.select=select
self.select = select
for a in args:
if args[a]:
setattr(self, a, args[a])
@ -96,21 +98,25 @@ class _column(object):
pass
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) )
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)
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,34 +127,38 @@ 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'
def __init__(self, string, size, **args):
_column.__init__(self, string=string, size=size, **args)
self._symbol_set = (self._symbol_c, self._symbol_set_char)
# takes a string (encoded in utf8) and returns a string (encoded in utf8)
def _symbol_set_char(self, symb):
#TODO:
# * we need to remove the "symb==False" from the next line BUT
#TODO:
# * we need to remove the "symb==False" from the next line BUT
# for now too many things rely on this broken behavior
# * the symb==None test should be common to all data types
if symb==None or symb==False:
if symb == None or symb == False:
return None
# we need to convert the string to a unicode object to be able
# we need to convert the string to a unicode object to be able
# to evaluate its length (and possibly truncate it) reliably
if isinstance(symb, str):
u_symb = unicode(symb, 'utf8')
@ -158,38 +168,46 @@ 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'
def __init__(self, selection, string='unknown', **args):
_column.__init__(self, string=string, **args)
self.selection = selection
@ -211,7 +229,7 @@ class one2one(_column):
_classic_read = False
_classic_write = True
_type = 'one2one'
def __init__(self, obj, string='unknown', **args):
warnings.warn("The one2one field doesn't work anymore", DeprecationWarning)
_column.__init__(self, string=string, **args)
@ -219,25 +237,26 @@ class one2one(_column):
def set(self, cr, obj_src, id, field, act, user=None, context=None):
if not context:
context={}
context = {}
obj = obj_src.pool.get(self._obj)
self._table = obj_src.pool.get(self._obj)._table
if act[0]==0:
if act[0] == 0:
id_new = obj.create(cr, user, act[1])
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (id_new,id))
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (id_new, id))
else:
cr.execute('select '+field+' from '+obj_src._table+' where id=%d', (act[0],))
id =cr.fetchone()[0]
obj.write(cr, user, [id] , act[1], context=context)
id = cr.fetchone()[0]
obj.write(cr, user, [id], act[1], context=context)
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)
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
_type = 'many2one'
def __init__(self, obj, string='unknown', **args):
_column.__init__(self, string=string, **args)
self._obj = obj
@ -254,9 +273,9 @@ class many2one(_column):
def get(self, cr, obj, ids, name, user=None, context=None, values=None):
if not context:
context={}
context = {}
if not values:
values={}
values = {}
res = {}
for r in values:
res[r['id']] = r[name]
@ -268,10 +287,10 @@ class many2one(_column):
try:
names = dict(obj.name_get(cr, user, filter(None, res.values()), context))
except except_orm:
names={}
names = {}
iids = filter(None, res.values())
cr.execute('select id,'+obj._rec_name+' from '+obj._table+' where id in ('+','.join(map(str,iids))+')')
cr.execute('select id,'+obj._rec_name+' from '+obj._table+' where id in ('+','.join(map(str, iids))+')')
for res22 in cr.fetchall():
names[res22[0]] = res22[1]
@ -284,36 +303,37 @@ class many2one(_column):
def set(self, cr, obj_src, id, field, values, user=None, context=None):
if not context:
context={}
context = {}
obj = obj_src.pool.get(self._obj)
self._table = obj_src.pool.get(self._obj)._table
if type(values)==type([]):
for act in values:
if act[0]==0:
if act[0] == 0:
id_new = obj.create(cr, act[2])
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (id_new,id))
elif act[0]==1:
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (id_new, id))
elif act[0] == 1:
obj.write(cr, [act[1]], act[2], context=context)
elif act[0]==2:
elif act[0] == 2:
cr.execute('delete from '+self._table+' where id=%d', (act[1],))
elif act[0]==3 or act[0]==5:
elif act[0] == 3 or act[0] == 5:
cr.execute('update '+obj_src._table+' set '+field+'=null where id=%d', (id,))
elif act[0]==4:
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (act[1],id))
elif act[0] == 4:
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (act[1], id))
else:
if values:
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (values,id))
cr.execute('update '+obj_src._table+' set '+field+'=%d where id=%d', (values, id))
else:
cr.execute('update '+obj_src._table+' set '+field+'=null where id=%d', (id,))
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)
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
_type = 'one2many'
def __init__(self, obj, fields_id, string='unknown', limit=None, **args):
_column.__init__(self, string=string, **args)
self._obj = obj
@ -330,42 +350,41 @@ class one2many(_column):
res = {}
for id in ids:
res[id] = []
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id, 'in', ids)], limit=self._limit)
for r in obj.pool.get(self._obj).read(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
if r[self._fields_id] in res:
res[r[self._fields_id]].append( r['id'] )
res[r[self._fields_id]].append(r['id'])
return res
def set_memory(self, cr, obj, id, field, values, user=None, context=None):
if not context:
context={}
context = {}
if not values:
return
obj = obj.pool.get(self._obj)
for act in values:
if act[0]==0:
if act[0] == 0:
act[2][self._fields_id] = id
obj.create(cr, user, act[2], context=context)
elif act[0]==1:
obj.write(cr, user, [act[1]] , act[2], context=context)
elif act[0]==2:
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
obj.unlink(cr, user, [act[1]], context=context)
elif act[0]==3:
elif act[0] == 3:
obj.datas[act[1]][self._fields_id] = False
elif act[0]==4:
elif act[0] == 4:
obj.datas[act[1]] = id
elif act[0]==5:
elif act[0] == 5:
for o in obj.datas.values():
if o[self._fields_id]==id:
if o[self._fields_id] == id:
o[self._fields_id] = False
elif act[0]==6:
elif act[0] == 6:
for id2 in (act[2] or []):
obj.datas[id2][self._fields_id] = id
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 = {}
@ -374,33 +393,33 @@ class one2many(_column):
res = {}
for id in ids:
res[id] = []
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id, 'in', ids)], limit=self._limit)
for r in obj.pool.get(self._obj)._read_flat(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
res[r[self._fields_id]].append( r['id'] )
res[r[self._fields_id]].append(r['id'])
return res
def set(self, cr, obj, id, field, values, user=None, context=None):
if not context:
context={}
context = {}
if not values:
return
_table = obj.pool.get(self._obj)._table
obj = obj.pool.get(self._obj)
for act in values:
if act[0]==0:
if act[0] == 0:
act[2][self._fields_id] = id
obj.create(cr, user, act[2], context=context)
elif act[0]==1:
obj.write(cr, user, [act[1]] , act[2], context=context)
elif act[0]==2:
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
obj.unlink(cr, user, [act[1]], context=context)
elif act[0]==3:
elif act[0] == 3:
cr.execute('update '+_table+' set '+self._fields_id+'=null where id=%d', (act[1],))
elif act[0]==4:
cr.execute('update '+_table+' set '+self._fields_id+'=%d where id=%d', (id,act[1]))
elif act[0]==5:
elif act[0] == 4:
cr.execute('update '+_table+' set '+self._fields_id+'=%d where id=%d', (id, act[1]))
elif act[0] == 5:
cr.execute('update '+_table+' set '+self._fields_id+'=null where '+self._fields_id+'=%d', (id,))
elif act[0]==6:
elif act[0] == 6:
if not act[2]:
ids2 = [0]
else:
@ -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
@ -424,7 +445,7 @@ class many2many(_column):
_classic_read = False
_classic_write = False
_type = 'many2many'
def __init__(self, obj, rel, id1, id2, string='unknown', limit=None, **args):
_column.__init__(self, string=string, **args)
self._obj = obj
@ -435,15 +456,15 @@ class many2many(_column):
def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
if not context:
context={}
context = {}
if not values:
values={}
values = {}
res = {}
if not ids:
return res
for id in ids:
res[id] = []
ids_s = ','.join(map(str,ids))
ids_s = ','.join(map(str, ids))
limit_str = self._limit is not None and ' limit %d' % self._limit or ''
obj = obj.pool.get(self._obj)
@ -463,39 +484,39 @@ class many2many(_column):
def set(self, cr, obj, id, name, values, user=None, context=None):
if not context:
context={}
context = {}
if not values:
return
obj = obj.pool.get(self._obj)
for act in values:
if act[0]==0:
if act[0] == 0:
idnew = obj.create(cr, user, act[2])
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%d,%d)', (id,idnew))
elif act[0]==1:
obj.write(cr, user, [act[1]] , act[2], context=context)
elif act[0]==2:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%d,%d)', (id, idnew))
elif act[0] == 1:
obj.write(cr, user, [act[1]], act[2], context=context)
elif act[0] == 2:
obj.unlink(cr, user, [act[1]], context=context)
elif act[0]==3:
cr.execute('delete from '+self._rel+' where ' + self._id1 + '=%d and '+ self._id2 + '=%d', (id,act[1]))
elif act[0]==4:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%d,%d)', (id,act[1]))
elif act[0]==5:
elif act[0] == 3:
cr.execute('delete from '+self._rel+' where ' + self._id1 + '=%d and '+ self._id2 + '=%d', (id, act[1]))
elif act[0] == 4:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%d,%d)', (id, act[1]))
elif act[0] == 5:
cr.execute('update '+self._rel+' set '+self._id2+'=null where '+self._id2+'=%d', (id,))
elif act[0]==6:
elif act[0] == 6:
d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
d1, d2 = obj.pool.get('ir.rule').domain_get(cr, user, obj._name)
if d1:
d1 = ' and '+d1
cr.execute('delete from '+self._rel+' where '+self._id1+'=%d AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+obj._table+' WHERE '+self._rel+'.'+self._id1+'=%d AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2 )
cr.execute('delete from '+self._rel+' where '+self._id1+'=%d AND '+self._id2+' IN (SELECT '+self._rel+'.'+self._id2+' FROM '+self._rel+', '+obj._table+' WHERE '+self._rel+'.'+self._id1+'=%d AND '+self._rel+'.'+self._id2+' = '+obj._table+'.id '+ d1 +')', [id, id]+d2)
for act_nbr in act[2]:
for act_nbr in act[2]:
cr.execute('insert into '+self._rel+' ('+self._id1+','+self._id2+') values (%d, %d)', (id, act_nbr))
#
# TODO: use a name_search
#
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name',operator,value)], offset, limit)
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name', operator, value)], offset, limit)
def get_memory(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
result = {}
@ -508,32 +529,31 @@ class many2many(_column):
return
for act in values:
# TODO: use constants instead of these magic numbers
if act[0]==0:
if act[0] == 0:
raise _('Not Implemented')
elif act[0]==1:
elif act[0] == 1:
raise _('Not Implemented')
elif act[0]==2:
elif act[0] == 2:
raise _('Not Implemented')
elif act[0]==3:
elif act[0] == 3:
raise _('Not Implemented')
elif act[0]==4:
elif act[0] == 4:
raise _('Not Implemented')
elif act[0]==5:
elif act[0] == 5:
raise _('Not Implemented')
elif act[0]==6:
elif act[0] == 6:
obj.datas[id][name] = act[2]
# ---------------------------------------------------------
# Function fields
# ---------------------------------------------------------
class function(_column):
_classic_read = False
_classic_write = False
_type = 'function'
_properties = True
def __init__(self, fnct, arg=None, fnct_inv=None, fnct_inv_arg=None, type='float', fnct_search=None, obj=None, method=False, store=False, **args):
_column.__init__(self, **args)
self._obj = obj
@ -553,7 +573,7 @@ class function(_column):
self._symbol_c = '%f'
self._symbol_f = lambda x: __builtin__.float(x or 0.0)
self._symbol_set = (self._symbol_c, self._symbol_f)
def search(self, cr, uid, obj, name, args):
if not self._fnct_search:
#CHECKME: should raise an exception
@ -562,9 +582,9 @@ class function(_column):
def get(self, cr, obj, ids, name, user=None, context=None, values=None):
if not context:
context={}
context = {}
if not values:
values={}
values = {}
res = {}
table = obj._table
if self._method:
@ -575,10 +595,11 @@ class function(_column):
def set(self, cr, obj, id, name, value, user=None, context=None):
if not context:
context={}
context = {}
if self._fnct_inv:
self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
# ---------------------------------------------------------
# Serialized fields
# ---------------------------------------------------------
@ -596,7 +617,7 @@ class property(function):
def _fnct_write(self, obj, cr, uid, id, prop, id_val, val, context=None):
if not context:
context={}
context = {}
(obj_dest,) = val
definition_id = self._field_get(cr, uid, obj._name, prop)
@ -629,7 +650,7 @@ class property(function):
def _fnct_read(self, obj, cr, uid, ids, prop, val, context=None):
if not context:
context={}
context = {}
property = obj.pool.get('ir.property')
definition_id = self._field_get(cr, uid, obj._name, prop)
@ -646,7 +667,7 @@ class property(function):
res = {}
for id in ids:
res[id]= default_val
res[id] = default_val
for prop in property.browse(cr, uid, nids):
res[int(prop.res_id.split(',')[1])] = (prop.value and \
int(prop.value.split(',')[1])) or False

File diff suppressed because it is too large Load Diff

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={}
@ -46,7 +47,7 @@ def get_db_and_pool(db_name, force_demo=False, status=None, update_module=False)
logger.notifyChannel('pooler', netsvc.LOG_INFO, 'Connecting to %s' % (db_name))
db = sql_db.db_connect(db_name)
db_dic[db_name] = db
if db_name in pool_dic:
pool = pool_dic[db_name]
else:
@ -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

@ -50,7 +50,7 @@ __builtin__.__dict__['tinyerp_version_string'] = "Tiny ERP Server " + __version_
#----------------------------------------------------------
# python imports
#----------------------------------------------------------
import sys,os,signal
import sys, os, signal
#----------------------------------------------------------
# ubuntu 8.04 has obsoleted `pyxml` package and installs here.
# the path needs to be updated before any `import xml`
@ -75,9 +75,9 @@ logger = netsvc.Logger()
import tools
import time
if sys.platform=='win32':
if sys.platform == 'win32':
import mx.DateTime
mx.DateTime.strptime = lambda x,y: mx.DateTime.mktime(time.strptime(x, y))
mx.DateTime.strptime = lambda x, y: mx.DateTime.mktime(time.strptime(x, y))
#os.chdir(tools.file_path_root)
@ -104,9 +104,9 @@ try:
except psycopg.OperationalError, err:
logger.notifyChannel("init", netsvc.LOG_ERROR, "could not connect to database '%s'!" % (tools.config["db_name"],))
msg = str(err).replace("FATAL:","").strip()
msg = str(err).replace("FATAL:", "").strip()
db_msg = "database \"%s\" does not exist" % (tools.config["db_name"],)
# Note: this is ugly but since psycopg only uses one exception for all errors
# I don't think it's possible to do differently
if msg == db_msg:
@ -165,7 +165,7 @@ if tools.config['upgrade']:
tools.config['update'][m] = 1
#----------------------------------------------------------
# import basic modules
# import basic modules
#----------------------------------------------------------
import osv, workflow, report, service
@ -190,7 +190,7 @@ if tools.config["translate_out"]:
buf = file(tools.config["translate_out"], "w")
tools.trans_export(tools.config["language"], tools.config["translate_modules"], buf, fileformat)
buf.close()
logger.notifyChannel("init", netsvc.LOG_INFO, 'translation file written succesfully')
sys.exit(0)
@ -217,12 +217,12 @@ if tools.config['xmlrpc']:
sys.exit(1)
interface = tools.config["interface"]
secure = tools.config["secure"]
httpd = netsvc.HttpDaemon(interface,port, secure)
httpd = netsvc.HttpDaemon(interface, port, secure)
if tools.config["xmlrpc"]:
xml_gw = netsvc.xmlrpc.RpcGateway('web-services')
httpd.attach("/xmlrpc", xml_gw )
httpd.attach("/xmlrpc", xml_gw)
logger.notifyChannel("web-services", netsvc.LOG_INFO,
"starting XML-RPC" + \
(tools.config['secure'] and ' Secure' or '') + \
@ -242,10 +242,11 @@ if tools.config['netrpc']:
logger.notifyChannel("init", netsvc.LOG_ERROR, "invalid port '%s'!" % (tools.config["netport"],))
sys.exit(1)
netinterface = tools.config["netinterface"]
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']:
@ -259,8 +260,8 @@ def handler(signum, frame):
from tools import config
if config['pidfile']:
fd=open(config['pidfile'], 'w')
pidtext="%d" % (os.getpid())
fd = open(config['pidfile'], 'w')
pidtext = "%d" % (os.getpid())
fd.write(pidtext)
fd.close()