Files
tryton/tryton/rpc.py
T

179 lines
4.7 KiB
Python

import pysocket
import logging
import socket
from threading import Semaphore
_SOCK = None
_USER = 0
_USERNAME = ''
_SESSION = ''
_DATABASE = ''
CONTEXT = {}
_VIEW_CACHE = {}
TIMEZONE = 'utc'
SECURE = False
_SEMAPHORE = Semaphore()
def db_list(host, port):
global _SOCK
_SEMAPHORE.acquire()
try:
try:
if _SOCK and _SOCK.hostname != host and _SOCK.port != port:
_SOCK.disconnect()
_SOCK = None
if _SOCK is None:
_SOCK = pysocket.PySocket()
_SOCK.connect(host, port)
try:
_SOCK.send(('db', 'list'))
except Exception, exception:
if exception[0] == 32:
_SOCK.reconnect()
_SOCK.send(('db', 'list'))
else:
raise
res = _SOCK.receive()
finally:
_SEMAPHORE.release()
return res
except:
_SOCK = None
return None
def db_exec(host, port, method, *args):
global _SOCK
_SEMAPHORE.acquire()
try:
try:
if _SOCK and _SOCK.hostname != host and _SOCK.port != port:
_SOCK.disconnect()
_SOCK = None
if _SOCK is None:
_SOCK= pysocket.PySocket()
_SOCK.connect(host, port)
_SOCK.send(('db', method) + args)
res = _SOCK.receive()
finally:
_SEMAPHORE.release()
return res
except:
_SOCK = None
raise
def login(username, password, host, port, database):
global _SOCK, _USER, _USERNAME, _SESSION, _DATABASE, _VIEW_CACHE, SECURE
_VIEW_CACHE = {}
SECURE = False
try:
_SEMAPHORE.acquire()
try:
if _SOCK and _SOCK.hostname != host and _SOCK.port != port:
_SOCK.disconnect()
_SOCK = None
if _SOCK is None:
_SOCK = pysocket.PySocket()
_SOCK.connect(host, port)
_SOCK.send(('common', 'login', database, username, password))
res = _SOCK.receive()
finally:
_SEMAPHORE.release()
except socket.error:
_SOCK = None
_USER = 0
_SESSION = ''
return -1
if not res:
_USER = 0
_SESSION = ''
return -2
_USER = res[0]
_USERNAME = username
_SESSION = res[1]
_DATABASE = database
SECURE = _SOCK.ssl
context_reload()
return 1
def logout():
global _SOCK, _USER, _USERNAME, _SESSION, _DATABASE, _VIEW_CACHE
if _SOCK:
_SOCK.disconnect()
_SOCK = None
_USER = 0
_USERNAME = ''
_SESSION = ''
_DATABASE = ''
_VIEW_CACHE = {}
def context_reload():
global CONTEXT, TIMEZONE
CONTEXT = {}
user = RPCProxy('res.user')
lang = RPCProxy('ir.lang')
try:
context = user.get_preferences(True, {})
except:
return
for i in context:
value = context[i]
CONTEXT[i] = value
if i == 'timezone':
try:
TIMEZONE = execute('common', 'timezone_get')
except:
pass
def execute(obj, method, *args):
global _SOCK, _DATABASE, _USER, _SESSION
if not _SOCK:
raise Exception('Not logged!')
logging.getLogger('rpc.request').info(str((obj, method, args)))
key = False
if len(args) >= 7 and args[3] == 'fields_view_get':
key = str(args)
if key in _VIEW_CACHE and _VIEW_CACHE[key][0]:
args = args[:]
args = args + (_VIEW_CACHE[key][0],)
try:
_SEMAPHORE.acquire()
try:
_SOCK.send((obj, method, _DATABASE, _USER, _SESSION) + args)
result = _SOCK.receive()
finally:
_SEMAPHORE.release()
except socket.error:
_SEMAPHORE.acquire()
try:
_SOCK.reconnect()
_SOCK.send((obj, method, _DATABASE, _USER, _SESSION) + args)
result = _SOCK.receive()
finally:
_SEMAPHORE.release()
if key:
if result is True and key in _VIEW_CACHE:
result = _VIEW_CACHE[key][1]
else:
_VIEW_CACHE[key] = (result['md5'], result)
return result
class RPCProxy(object):
def __init__(self, name):
self.name = name
self.__attrs = {}
def __getattr__(self, attr):
if attr not in self.__attrs:
self.__attrs[attr] = RPCFunction(self.name, attr)
return self.__attrs[attr]
class RPCFunction(object):
def __init__(self, name, func_name):
self.name = name
self.func = func_name
def __call__(self, *args):
return execute('object', 'execute', self.name, self.func, *args)