2011-03-02 18:56:06 +00:00
#!/usr/bin/python
2011-03-25 09:41:19 +00:00
import datetime
2011-03-30 14:35:56 +00:00
import dateutil . relativedelta
2011-03-17 13:09:46 +00:00
import functools
2011-03-21 08:13:31 +00:00
import optparse
import os
import sys
import tempfile
2011-03-30 14:35:56 +00:00
import time
2011-03-21 08:13:31 +00:00
import traceback
import uuid
import xmlrpclib
2011-03-02 18:56:06 +00:00
2011-03-17 12:51:07 +00:00
import cherrypy
2011-03-08 14:57:54 +00:00
import cherrypy . lib . static
2011-03-10 15:53:45 +00:00
import simplejson
2011-03-02 18:56:06 +00:00
2011-03-28 14:19:20 +00:00
import nonliterals
2011-04-07 09:59:12 +00:00
import logging
2011-03-02 18:56:06 +00:00
2011-04-07 03:04:29 +00:00
#-----------------------------------------------------------
# Globals
#-----------------------------------------------------------
path_root = os . path . dirname ( os . path . dirname ( os . path . normpath ( __file__ ) ) )
path_addons = os . path . join ( path_root , ' addons ' )
cherrypy_root = None
#-----------------------------------------------------------
# Per Database Globals (might move into a pool if needed)
#-----------------------------------------------------------
applicationsession = { }
addons_module = { }
addons_manifest = { }
controllers_class = { }
controllers_object = { }
controllers_path = { }
2011-03-02 18:56:06 +00:00
#----------------------------------------------------------
# OpenERP Client Library
#----------------------------------------------------------
class OpenERPUnboundException ( Exception ) :
pass
class OpenERPConnector ( object ) :
pass
class OpenERPAuth ( object ) :
pass
class OpenERPModel ( object ) :
2011-03-21 08:13:31 +00:00
def __init__ ( self , session , model ) :
2011-03-02 18:56:06 +00:00
self . _session = session
self . _model = model
2011-03-21 08:13:31 +00:00
def __getattr__ ( self , name ) :
return lambda * l : self . _session . execute ( self . _model , name , * l )
2011-03-02 18:56:06 +00:00
class OpenERPSession ( object ) :
2011-03-25 09:41:19 +00:00
"""
An OpenERP RPC session , a given user can own multiple such sessions
in a web session .
. . attribute : : context
The session context , a ` ` dict ` ` . Can be reloaded by calling
: meth : ` openerpweb . openerpweb . OpenERPSession . get_context `
2011-03-28 12:27:24 +00:00
. . attribute : : domains_store
A ` ` dict ` ` matching domain keys to evaluable ( but non - literal ) domains .
Used to store references to non - literal domains which need to be
round - tripped to the client browser .
2011-03-25 09:41:19 +00:00
"""
2011-07-09 16:12:00 +00:00
def __init__ ( self , server = ' 127.0.0.1 ' , port = 8069 , model_factory = OpenERPModel ) :
2011-03-02 18:56:06 +00:00
self . _server = server
self . _port = port
self . _db = False
self . _uid = False
self . _login = False
self . _password = False
2011-03-21 10:47:35 +00:00
self . model_factory = model_factory
2011-04-07 16:41:06 +00:00
self . _locale = ' en_US '
2011-03-25 09:41:19 +00:00
self . context = { }
2011-03-29 08:20:02 +00:00
self . contexts_store = { }
2011-03-28 12:27:24 +00:00
self . domains_store = { }
2011-04-07 16:41:06 +00:00
self . _lang = { }
self . remote_timezone = ' utc '
self . client_timezone = False
2011-03-25 09:41:19 +00:00
2011-03-02 18:56:06 +00:00
def proxy ( self , service ) :
2011-05-02 13:19:04 +00:00
s = xmlrpclib . ServerProxy ( ' http:// %s : %s /xmlrpc/ %s ' % ( self . _server , self . _port , service ) )
2011-03-02 18:56:06 +00:00
return s
def bind ( self , db , uid , password ) :
self . _db = db
self . _uid = uid
self . _password = password
def login ( self , db , login , password ) :
uid = self . proxy ( ' common ' ) . login ( db , login , password )
self . bind ( db , uid , password )
self . _login = login
2011-04-07 16:41:06 +00:00
2011-03-25 09:41:19 +00:00
if uid : self . get_context ( )
2011-03-02 18:56:06 +00:00
return uid
2011-03-21 08:13:31 +00:00
def execute ( self , model , func , * l , * * d ) :
2011-03-02 18:56:06 +00:00
if not ( self . _db and self . _uid and self . _password ) :
raise OpenERPUnboundException ( )
r = self . proxy ( ' object ' ) . execute ( self . _db , self . _uid , self . _password , model , func , * l , * * d )
return r
2011-04-21 15:56:05 +00:00
def exec_workflow ( self , model , id , signal ) :
if not ( self . _db and self . _uid and self . _password ) :
raise OpenERPUnboundException ( )
r = self . proxy ( ' object ' ) . exec_workflow ( self . _db , self . _uid , self . _password , model , signal , id )
return r
2011-03-21 08:13:31 +00:00
def model ( self , model ) :
2011-03-25 09:41:19 +00:00
""" Get an RPC proxy for the object ``model``, bound to this session.
: param model : an OpenERP model name
: type model : str
: rtype : : class : ` openerpweb . openerpweb . OpenERPModel `
"""
2011-03-21 10:47:35 +00:00
return self . model_factory ( self , model )
2011-03-25 09:41:19 +00:00
def get_context ( self ) :
""" Re-initializes the current user ' s session context (based on
his preferences ) by calling res . users . get_context ( ) with the old
context
: returns : the new context
"""
assert self . _uid , " The user needs to be logged-in to initialize his context "
self . context = self . model ( ' res.users ' ) . context_get ( self . context )
2011-06-20 10:58:18 +00:00
self . context = self . context or { }
2011-06-28 13:30:44 +00:00
2011-04-07 16:41:06 +00:00
self . client_timezone = self . context . get ( " tz " , False )
2011-04-28 13:50:45 +00:00
# invalid code, anyway we decided the server will be in UTC
#if self.client_timezone:
# self.remote_timezone = self.execute('common', 'timezone_get')
2011-06-28 13:30:44 +00:00
2011-04-07 16:41:06 +00:00
self . _locale = self . context . get ( ' lang ' , ' en_US ' )
lang_ids = self . execute ( ' res.lang ' , ' search ' , [ ( ' code ' , ' = ' , self . _locale ) ] )
if lang_ids :
self . _lang = self . execute ( ' res.lang ' , ' read ' , lang_ids [ 0 ] , [ ] )
2011-03-25 09:41:19 +00:00
return self . context
@property
def base_eval_context ( self ) :
""" Default evaluation context for the session.
Used to evaluate contexts and domains .
"""
2011-03-28 12:27:24 +00:00
base = dict (
2011-03-25 09:41:19 +00:00
uid = self . _uid ,
current_date = datetime . date . today ( ) . strftime ( ' % Y- % m- %d ' ) ,
time = time ,
datetime = datetime ,
2011-03-28 12:27:24 +00:00
relativedelta = dateutil . relativedelta . relativedelta
2011-03-25 09:41:19 +00:00
)
2011-03-28 12:27:24 +00:00
base . update ( self . context )
return base
def evaluation_context ( self , context = None ) :
""" Returns the session ' s evaluation context, augmented with the
provided context if any .
: param dict context : to add merge in the session ' s base eval context
: returns : the augmented context
: rtype : dict
"""
2011-07-15 09:24:51 +00:00
d = dict ( self . base_eval_context )
2011-03-28 12:27:24 +00:00
if context :
d . update ( context )
2011-07-15 09:24:51 +00:00
d [ ' context ' ] = d
2011-03-28 12:27:24 +00:00
return d
2011-03-25 09:41:19 +00:00
2011-03-28 15:14:10 +00:00
def eval_context ( self , context_to_eval , context = None ) :
""" Evaluates the provided context_to_eval in the context (haha) of
2011-06-17 16:31:53 +00:00
the context . Also merges the evaluated context with the session ' s context.
2011-03-25 09:41:19 +00:00
2011-03-28 15:14:10 +00:00
: param context_to_eval : a context to evaluate . Must be a dict or a
non - literal context . If it ' s a dict, will be
returned as - is
: type context_to_eval : openerpweb . nonliterals . Context
2011-03-25 09:41:19 +00:00
: returns : the evaluated context
: rtype : dict
2011-03-28 15:14:10 +00:00
: raises : ` ` TypeError ` ` if ` ` context_to_eval ` ` is neither a dict nor
a Context
2011-03-25 09:41:19 +00:00
"""
2011-06-17 16:08:49 +00:00
ctx = dict (
self . base_eval_context ,
* * ( context or { } ) )
2011-06-17 16:31:53 +00:00
# adding the context of the session to send to the openerp server
2011-06-29 10:28:58 +00:00
ccontext = nonliterals . CompoundContext ( self . context , context_to_eval or { } )
2011-06-17 16:31:53 +00:00
ccontext . session = self
return ccontext . evaluate ( ctx )
2011-03-25 12:32:52 +00:00
2011-03-28 14:19:20 +00:00
def eval_domain ( self , domain , context = None ) :
2011-03-28 15:14:10 +00:00
""" Evaluates the provided domain using the provided context
2011-03-25 09:41:19 +00:00
( merged with the session ' s evaluation context)
2011-03-28 15:14:10 +00:00
: param domain : an OpenERP domain as a list or as a
2011-03-28 14:19:20 +00:00
: class : ` openerpweb . nonliterals . Domain ` instance
2011-03-25 09:41:19 +00:00
2011-03-28 14:19:20 +00:00
In the second case , it will be evaluated and returned .
: type domain : openerpweb . nonliterals . Domain
2011-03-25 09:41:19 +00:00
: param dict context : the context to use in the evaluation , if any .
: returns : the evaluated domain
: rtype : list
2011-03-28 14:19:20 +00:00
2011-03-28 15:14:10 +00:00
: raises : ` ` TypeError ` ` if ` ` domain ` ` is neither a list nor a Domain
2011-03-25 09:41:19 +00:00
"""
2011-03-28 14:19:20 +00:00
if isinstance ( domain , list ) :
return domain
2011-03-25 09:41:19 +00:00
2011-06-17 16:31:53 +00:00
cdomain = nonliterals . CompoundDomain ( domain )
cdomain . session = self
2011-07-15 09:24:51 +00:00
return cdomain . evaluate ( context or { } )
2011-03-25 12:32:52 +00:00
2011-03-02 18:56:06 +00:00
#----------------------------------------------------------
# OpenERP Web RequestHandler
#----------------------------------------------------------
class JsonRequest ( object ) :
2011-07-09 16:12:00 +00:00
""" JSON-RPC2 over HTTP.
2011-03-02 18:56:06 +00:00
2011-04-14 21:43:32 +00:00
Sucessful request : :
- - > { " jsonrpc " : " 2.0 " ,
" method " : " call " ,
" params " : { " session_id " : " SID " ,
" context " : { } ,
" arg1 " : " val1 " } ,
" id " : null }
< - - { " jsonrpc " : " 2.0 " ,
" result " : { " res1 " : " val1 " } ,
" id " : null }
Request producing a error : :
- - > { " jsonrpc " : " 2.0 " ,
" method " : " call " ,
" params " : { " session_id " : " SID " ,
" context " : { } ,
" arg1 " : " val1 " } ,
" id " : null }
< - - { " jsonrpc " : " 2.0 " ,
" error " : { " code " : 1 ,
" message " : " End user error message. " ,
" data " : { " code " : " codestring " ,
" debug " : " traceback " } } ,
" id " : null }
2011-03-02 18:56:06 +00:00
"""
def parse ( self , request ) :
2011-04-06 00:51:36 +00:00
self . request = request
2011-03-21 08:13:31 +00:00
self . params = request . get ( " params " , { } )
2011-04-07 03:04:29 +00:00
self . applicationsession = applicationsession
2011-07-13 10:26:12 +00:00
self . httprequest = cherrypy . request
self . httpresponse = cherrypy . response
self . httpsession = cherrypy . session
2011-04-06 00:51:36 +00:00
self . httpsession_id = " cookieid "
self . httpsession = cherrypy . session
2011-03-17 17:14:01 +00:00
self . session_id = self . params . pop ( " session_id " , None ) or uuid . uuid4 ( ) . hex
2011-07-09 16:12:00 +00:00
host = cherrypy . config [ ' openerp.server.host ' ]
port = cherrypy . config [ ' openerp.server.port ' ]
self . session = self . httpsession . setdefault ( self . session_id , OpenERPSession ( host , port ) )
2011-03-17 14:06:27 +00:00
self . context = self . params . pop ( ' context ' , None )
return self . params
def dispatch ( self , controller , method , requestf = None , request = None ) :
2011-07-11 11:48:27 +00:00
""" Calls the method asked for by the JSON-RPC2 request
2011-03-17 14:06:27 +00:00
: param controller : the instance of the controller which received the request
: type controller : type
: param method : the method which received the request
: type method : callable
: param requestf : a file - like object containing an encoded JSON - RPC2 request
: type requestf : < read ( ) - > bytes >
: param request : an encoded JSON - RPC2 request
: type request : bytes
: returns : a string - encoded JSON - RPC2 reply
: rtype : bytes
2011-07-11 11:48:27 +00:00
"""
2011-04-07 02:47:48 +00:00
# Read POST content or POST Form Data named "request"
2011-03-17 14:06:27 +00:00
if requestf :
2011-04-06 00:51:36 +00:00
request = simplejson . load ( requestf , object_hook = nonliterals . non_literal_decoder )
2011-03-17 14:06:27 +00:00
else :
2011-04-06 00:51:36 +00:00
request = simplejson . loads ( request , object_hook = nonliterals . non_literal_decoder )
2011-07-11 11:48:27 +00:00
response = { " jsonrpc " : " 2.0 " , " id " : request . get ( ' id ' ) }
2011-03-02 18:56:06 +00:00
try :
2011-03-21 08:13:31 +00:00
print " --> %s . %s %s " % ( controller . __class__ . __name__ , method . __name__ , request )
2011-03-17 14:06:27 +00:00
error = None
2011-04-06 00:51:36 +00:00
self . parse ( request )
2011-07-11 11:48:27 +00:00
response [ " result " ] = method ( controller , self , * * self . params )
2011-03-17 14:06:27 +00:00
except OpenERPUnboundException :
error = {
2011-03-17 15:47:46 +00:00
' code ' : 100 ,
2011-03-17 14:06:27 +00:00
' message ' : " OpenERP Session Invalid " ,
' data ' : {
' type ' : ' session_invalid ' ,
' debug ' : traceback . format_exc ( )
}
}
2011-03-02 18:56:06 +00:00
except xmlrpclib . Fault , e :
2011-03-17 14:06:27 +00:00
error = {
2011-03-17 15:47:46 +00:00
' code ' : 200 ,
2011-03-17 14:06:27 +00:00
' message ' : " OpenERP Server Error " ,
' data ' : {
2011-03-17 15:47:46 +00:00
' type ' : ' server_exception ' ,
2011-03-17 14:06:27 +00:00
' fault_code ' : e . faultCode ,
2011-03-21 08:13:31 +00:00
' debug ' : " Client %s \n Server %s " % (
" " . join ( traceback . format_exception ( " " , None , sys . exc_traceback ) ) , e . faultString )
2011-03-17 14:06:27 +00:00
}
}
except Exception :
2011-04-07 09:59:12 +00:00
cherrypy . log ( " An error occured while handling a json request " ,
severity = logging . ERROR , traceback = True )
2011-03-17 14:06:27 +00:00
error = {
2011-03-17 15:47:46 +00:00
' code ' : 300 ,
2011-03-17 14:06:27 +00:00
' message ' : " OpenERP WebClient Error " ,
' data ' : {
' type ' : ' client_exception ' ,
' debug ' : " Client %s " % traceback . format_exc ( )
}
}
if error :
response [ " error " ] = error
2011-03-21 08:13:31 +00:00
print " <-- " , response
2011-03-02 18:56:06 +00:00
print
2011-03-17 15:59:14 +00:00
2011-04-06 00:51:36 +00:00
content = simplejson . dumps ( response , cls = nonliterals . NonLiteralEncoder )
2011-03-17 15:59:14 +00:00
cherrypy . response . headers [ ' Content-Type ' ] = ' application/json '
cherrypy . response . headers [ ' Content-Length ' ] = len ( content )
return content
2011-03-02 18:56:06 +00:00
def jsonrequest ( f ) :
2011-03-17 13:09:46 +00:00
@cherrypy.expose
@functools.wraps ( f )
2011-04-07 02:47:48 +00:00
def json_handler ( controller ) :
return JsonRequest ( ) . dispatch ( controller , f , requestf = cherrypy . request . body )
2011-03-21 08:13:31 +00:00
2011-03-17 13:09:46 +00:00
return json_handler
2011-03-02 18:56:06 +00:00
2011-03-07 09:26:32 +00:00
class HttpRequest ( object ) :
2011-03-02 18:56:06 +00:00
""" Regular GET/POST request
"""
2011-04-07 02:47:48 +00:00
def dispatch ( self , controller , f , request , * * kw ) :
self . request = request
2011-04-07 03:04:29 +00:00
self . applicationsession = applicationsession
2011-04-07 02:47:48 +00:00
self . httpsession_id = " cookieid "
self . httpsession = cherrypy . session
2011-05-17 15:59:53 +00:00
self . context = kw . get ( ' context ' , { } )
2011-07-09 16:12:00 +00:00
host = cherrypy . config [ ' openerp.server.host ' ]
port = cherrypy . config [ ' openerp.server.port ' ]
2011-07-11 11:41:35 +00:00
self . session = self . httpsession . setdefault ( kw . get ( ' session_id ' ) , OpenERPSession ( host , port ) )
2011-03-02 18:56:06 +00:00
self . result = " "
2011-05-26 20:37:06 +00:00
if request . method == ' GET ' :
print " GET --> %s . %s %s %r " % ( controller . __class__ . __name__ , f . __name__ , request , kw )
else :
akw = dict ( [ ( key , kw [ key ] if isinstance ( kw [ key ] , basestring ) else type ( kw [ key ] ) ) for key in kw . keys ( ) ] )
print " POST --> %s . %s %s %r " % ( controller . __class__ . __name__ , f . __name__ , request , akw )
2011-04-07 02:47:48 +00:00
r = f ( controller , self , * * kw )
2011-04-07 03:04:29 +00:00
print " <-- " , r
print
2011-03-02 18:56:06 +00:00
return r
2011-03-07 09:26:32 +00:00
def httprequest ( f ) :
2011-03-02 18:56:06 +00:00
# check cleaner wrapping:
# functools.wraps(f)(lambda x: JsonRequest().dispatch(x, f))
2011-04-07 02:47:48 +00:00
def http_handler ( self , * l , * * kw ) :
2011-04-07 03:04:29 +00:00
return HttpRequest ( ) . dispatch ( self , f , cherrypy . request , * * kw )
2011-04-07 02:47:48 +00:00
http_handler . exposed = 1
return http_handler
2011-03-02 18:56:06 +00:00
#-----------------------------------------------------------
# Cherrypy stuff
#-----------------------------------------------------------
class ControllerType ( type ) :
def __init__ ( cls , name , bases , attrs ) :
super ( ControllerType , cls ) . __init__ ( name , bases , attrs )
2011-03-21 08:06:32 +00:00
controllers_class [ " %s . %s " % ( cls . __module__ , cls . __name__ ) ] = cls
2011-03-02 18:56:06 +00:00
class Controller ( object ) :
__metaclass__ = ControllerType
class Root ( object ) :
def __init__ ( self ) :
self . addons = { }
self . _load_addons ( )
2011-03-21 08:13:31 +00:00
2011-03-02 18:56:06 +00:00
def _load_addons ( self ) :
if path_addons not in sys . path :
2011-03-21 08:13:31 +00:00
sys . path . insert ( 0 , path_addons )
2011-03-02 18:56:06 +00:00
for i in os . listdir ( path_addons ) :
if i not in sys . modules :
2011-03-21 08:13:31 +00:00
manifest_path = os . path . join ( path_addons , i , ' __openerp__.py ' )
2011-03-07 09:26:32 +00:00
if os . path . isfile ( manifest_path ) :
manifest = eval ( open ( manifest_path ) . read ( ) )
2011-03-21 08:13:31 +00:00
print " Loading " , i
2011-03-07 09:26:32 +00:00
m = __import__ ( i )
addons_module [ i ] = m
addons_manifest [ i ] = manifest
2011-03-21 08:13:31 +00:00
for k , v in controllers_class . items ( ) :
2011-03-07 09:26:32 +00:00
if k not in controllers_object :
2011-03-02 18:56:06 +00:00
o = v ( )
2011-03-07 09:26:32 +00:00
controllers_object [ k ] = o
2011-03-21 08:13:31 +00:00
if hasattr ( o , ' _cp_path ' ) :
2011-03-07 09:26:32 +00:00
controllers_path [ o . _cp_path ] = o
2011-03-02 18:56:06 +00:00
def default ( self , * l , * * kw ) :
#print "default",l,kw
# handle static files
2011-03-21 08:13:31 +00:00
if len ( l ) > 2 and l [ 1 ] == ' static ' :
2011-03-02 18:56:06 +00:00
# sanitize path
p = os . path . normpath ( os . path . join ( * l ) )
2011-03-21 08:13:31 +00:00
return cherrypy . lib . static . serve_file ( os . path . join ( path_addons , p ) )
2011-03-02 18:56:06 +00:00
elif len ( l ) > 1 :
2011-03-21 17:03:57 +00:00
for i in range ( len ( l ) , 1 , - 1 ) :
2011-03-02 18:56:06 +00:00
ps = " / " + " / " . join ( l [ 0 : i ] )
2011-03-07 09:26:32 +00:00
if ps in controllers_path :
c = controllers_path [ ps ]
2011-03-02 18:56:06 +00:00
rest = l [ i : ] or [ ' index ' ]
meth = rest [ 0 ]
2011-03-21 08:13:31 +00:00
m = getattr ( c , meth )
if getattr ( m , ' exposed ' , 0 ) :
print " Calling " , ps , c , meth , m
2011-03-07 09:26:32 +00:00
return m ( * * kw )
2011-03-21 16:29:04 +00:00
raise cherrypy . NotFound ( ' / ' + ' / ' . join ( l ) )
2011-06-08 05:51:39 +00:00
elif l and l [ 0 ] == ' mobile ' :
2011-06-14 12:36:04 +00:00
#for the mobile web client we are supposed to use a different url to just add '/mobile'
2011-06-08 05:51:39 +00:00
raise cherrypy . HTTPRedirect ( ' /web_mobile/static/src/web_mobile.html ' , 301 )
2011-03-02 18:56:06 +00:00
else :
2011-03-30 14:35:56 +00:00
raise cherrypy . HTTPRedirect ( ' /base/static/src/base.html ' , 301 )
2011-03-02 18:56:06 +00:00
default . exposed = True
def main ( argv ) :
2011-04-28 15:16:08 +00:00
# change the timezone of the program to the OpenERP server's assumed timezone
os . environ [ " TZ " ] = " UTC "
2011-07-09 16:12:00 +00:00
2011-05-13 11:42:28 +00:00
DEFAULT_CONFIG = {
2011-03-20 13:21:46 +00:00
' server.socket_host ' : ' 0.0.0.0 ' ,
2011-03-02 18:56:06 +00:00
' tools.sessions.on ' : True ,
2011-03-18 14:18:36 +00:00
' tools.sessions.storage_type ' : ' file ' ,
' tools.sessions.timeout ' : 60
2011-03-02 18:56:06 +00:00
}
2011-07-09 16:12:00 +00:00
2011-05-13 11:42:28 +00:00
# Parse config
op = optparse . OptionParser ( )
2011-07-13 10:26:12 +00:00
op . add_option ( " -p " , " --port " , dest = " server.socket_port " , default = 8002 , help = " listening port " , type = " int " , metavar = " NUMBER " )
op . add_option ( " -s " , " --session-path " , dest = " tools.sessions.storage_path " , default = os . path . join ( tempfile . gettempdir ( ) , " cpsessions " ) , help = " directory used for session storage " , metavar = " DIR " )
op . add_option ( " --server-host " , dest = " openerp.server.host " , default = ' 127.0.0.1 ' , help = " OpenERP server hostname " , metavar = " HOST " )
op . add_option ( " --server-port " , dest = " openerp.server.port " , default = 8069 , help = " OpenERP server port " , type = " int " , metavar = " NUMBER " )
op . add_option ( " --db-filter " , dest = " openerp.dbfilter " , default = ' .* ' , help = " Filter listed database " , metavar = " REGEXP " )
2011-05-13 11:42:28 +00:00
( o , args ) = op . parse_args ( argv [ 1 : ] )
o = vars ( o )
for k in o . keys ( ) :
2011-07-11 11:39:53 +00:00
if o [ k ] is None :
2011-05-13 11:42:28 +00:00
del ( o [ k ] )
2011-03-02 18:56:06 +00:00
2011-03-20 13:21:46 +00:00
# Setup and run cherrypy
cherrypy . tree . mount ( Root ( ) )
2011-07-09 16:12:00 +00:00
2011-05-13 11:42:28 +00:00
cherrypy . config . update ( config = DEFAULT_CONFIG )
2011-07-13 10:26:12 +00:00
if os . path . exists ( os . path . join ( path_root , ' openerp-web.cfg ' ) ) :
cherrypy . config . update ( os . path . join ( path_root , ' openerp-web.cfg ' ) )
2011-05-13 11:42:28 +00:00
if os . path . exists ( os . path . expanduser ( ' ~/.openerp_webrc ' ) ) :
cherrypy . config . update ( os . path . expanduser ( ' ~/.openerp_webrc ' ) )
cherrypy . config . update ( o )
2011-07-09 16:12:00 +00:00
2011-05-13 11:42:28 +00:00
if not os . path . exists ( cherrypy . config [ ' tools.sessions.storage_path ' ] ) :
2011-07-09 16:12:00 +00:00
os . makedirs ( cherrypy . config [ ' tools.sessions.storage_path ' ] , 0700 )
2011-03-17 12:51:07 +00:00
cherrypy . server . subscribe ( )
cherrypy . engine . start ( )
cherrypy . engine . block ( )
2011-04-07 09:59:12 +00:00