report total
[odoo/odoo.git] / bin / tinyerp-server.py
1 #!/usr/bin/python
2
3 ##############################################################################
4 #
5 # Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be)
6 #
7 # $Id: tinyerp-server.py 1308 2005-09-08 18:02:01Z pinky $
8 #
9 # WARNING: This program as such is intended to be used by professional
10 # programmers who take the whole responsability of assessing all potential
11 # consequences resulting from its eventual inadequacies and bugs
12 # End users who are looking for a ready-to-use solution with commercial
13 # garantees and support are strongly adviced to contact a Free Software
14 # Service Company
15 #
16 # This program is Free Software; you can redistribute it and/or
17 # modify it under the terms of the GNU General Public License
18 # as published by the Free Software Foundation; either version 2
19 # of the License, or (at your option) any later version.
20 #
21 # This program is distributed in the hope that it will be useful,
22 # but WITHOUT ANY WARRANTY; without even the implied warranty of
23 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 # GNU General Public License for more details.
25 #
26 # You should have received a copy of the GNU General Public License
27 # along with this program; if not, write to the Free Software
28 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29 #
30 ##############################################################################
31
32 """
33 Tiny ERP - Server
34 Tiny ERP is an ERP+CRM program for small and medium businesses.
35
36 The whole source code is distributed under the terms of the
37 GNU Public Licence.
38
39 (c) 2003-TODAY, Fabien Pinckaers - Tiny sprl
40 """
41
42 __author__ = 'Fabien Pinckaers, <fp@tiny.be>'
43 __version__ = '4.1.1'
44
45 import __builtin__
46 __builtin__.__dict__['tinyerp_version'] = __version__
47 __builtin__.__dict__['tinyerp_version_string'] = "Tiny ERP Server " + __version__
48
49
50
51 #----------------------------------------------------------
52 # python imports
53 #----------------------------------------------------------
54 import os, signal, sys
55
56 #----------------------------------------------------------
57 # get logger
58 #----------------------------------------------------------
59 import netsvc
60
61 netsvc.init_logger()
62
63 logger = netsvc.Logger()
64
65 #-----------------------------------------------------------------------
66 # import the tools module so that the commandline parameters are parsed
67 #-----------------------------------------------------------------------
68 import tools
69 import time
70
71 if sys.platform=='win32':
72         import mx.DateTime
73         mx.DateTime.strptime = lambda x,y: mx.DateTime.mktime(time.strptime(x, y))
74
75 #os.chdir(tools.file_path_root)
76
77 #----------------------------------------------------------
78 # init net service
79 #----------------------------------------------------------
80 logger.notifyChannel("objects", netsvc.LOG_INFO, 'initialising distributed objects services')
81
82 dispatcher = netsvc.Dispatcher()
83 dispatcher.monitor(signal.SIGINT)
84
85 #---------------------------------------------------------------
86 # connect to the database and initialize it with base if needed
87 #---------------------------------------------------------------
88 logger.notifyChannel("init", netsvc.LOG_INFO, 'connecting to database')
89
90 import psycopg
91 import pooler
92
93 # try to connect to the database
94 try:
95 #       pooler.init()
96         pass
97 except psycopg.OperationalError, err:
98         logger.notifyChannel("init", netsvc.LOG_ERROR, "could not connect to database '%s'!" % (tools.config["db_name"],))
99
100         msg = str(err).replace("FATAL:","").strip()
101         db_msg = "database \"%s\" does not exist" % (tools.config["db_name"],)
102         
103         # Note: this is ugly but since psycopg only uses one exception for all errors
104         # I don't think it's possible to do differently
105         if msg == db_msg:
106                 print """
107     this database does not exist
108
109 You need to create it using the command:
110
111     createdb --encoding=UNICODE '%s'
112
113 When you run tinyerp-server for the first time it will initialise the
114 database. You may force this behaviour at a later time by using the command:
115
116     ./tinyerp-server --init=all
117
118 Two accounts will be created by default:
119     1. login: admin      password : admin
120     2. login: demo       password : demo
121
122 """ % (tools.config["db_name"])
123         else:
124                 print "\n    "+msg+"\n"
125         sys.exit(1)
126
127 db_name = tools.config["db_name"]
128
129 # test whether it is needed to initialize the db (the db is empty)
130 try:
131         cr = pooler.get_db_only(db_name).cursor()
132 except psycopg.OperationalError:
133         logger.notifyChannel("init", netsvc.LOG_INFO, "could not connect to database '%s'!" % db_name,)
134         cr = None
135 if cr:
136         cr.execute("SELECT relname FROM pg_class WHERE relkind='r' AND relname='perm'")
137         if len(cr.fetchall())==0:
138 #if False:
139                 logger.notifyChannel("init", netsvc.LOG_INFO, "init db")
140                 tools.init_db(cr)
141                 # in that case, force --init=all
142                 tools.config["init"]["all"] = 1
143                 tools.config['update']['all'] = 1
144                 if not tools.config['without_demo']:
145                         tools.config["demo"]['all'] = 1
146         cr.close()
147
148 #----------------------------------------------------------
149 # launch modules install/upgrade/removes if needed
150 #----------------------------------------------------------
151 if tools.config['upgrade']:
152         print 'Upgrading new modules...'
153         import tools.upgrade
154         (toinit, toupdate) = tools.upgrade.upgrade()
155         for m in toinit:
156                 tools.config['init'][m] = 1
157         for m in toupdate:
158                 tools.config['update'][m] = 1
159
160 #----------------------------------------------------------
161 # import basic modules 
162 #----------------------------------------------------------
163 import osv, workflow, report, service
164
165 #----------------------------------------------------------
166 # import addons
167 #----------------------------------------------------------
168 import addons
169
170 addons.register_classes()
171 if tools.config['init'] or tools.config['update']:
172         pooler.get_db_and_pool(tools.config['db_name'], update_module=True)
173
174 #----------------------------------------------------------
175 # translation stuff
176 #----------------------------------------------------------
177 if tools.config["translate_out"]:
178         import csv
179
180         logger.notifyChannel("init", netsvc.LOG_INFO, 'writing translation file for language %s to %s' % (tools.config["language"], tools.config["translate_out"]))
181         trans=tools.trans_generate(tools.config["language"], tools.config["translate_modules"])
182         writer=csv.writer(file(tools.config["translate_out"], "w"))
183         for row in trans:
184                 writer.writerow(row)
185         del trans
186         logger.notifyChannel("init", netsvc.LOG_INFO, 'translation file written succesfully')
187         sys.exit(0)
188
189 if tools.config["translate_in"]:
190         tools.trans_load(tools.config["db_name"], tools.config["translate_in"], tools.config["language"])
191         sys.exit(0)
192
193 #----------------------------------------------------------------------------------
194 # if we don't want the server to continue to run after initialization, we quit here
195 #----------------------------------------------------------------------------------
196 if tools.config["stop_after_init"]:
197     sys.exit(0)
198
199
200 #----------------------------------------------------------
201 # Launch Server
202 #----------------------------------------------------------
203
204 if tools.config['xmlrpc']:
205         try:
206                 port = int(tools.config["port"])
207         except Exception:
208                 logger.notifyChannel("init", netsvc.LOG_ERROR, "invalid port '%s'!" % (tools.config["port"],))
209                 sys.exit(1)
210         interface = tools.config["interface"]
211         secure = tools.config["secure"]
212         
213         httpd = netsvc.HttpDaemon(interface,port, secure)
214         
215         if tools.config["xmlrpc"]:
216                 xml_gw = netsvc.xmlrpc.RpcGateway('web-services')
217                 httpd.attach("/xmlrpc", xml_gw )
218                 logger.notifyChannel("web-services", netsvc.LOG_INFO, "starting XML-RPC services, port "+str(port))
219         
220         #
221         #if tools.config["soap"]:
222         #       soap_gw = netsvc.xmlrpc.RpcGateway('web-services')
223         #       httpd.attach("/soap", soap_gw )
224         #       logger.notifyChannel("web-services", netsvc.LOG_INFO, 'starting SOAP services, port '+str(port))
225         #
226         if not (netsvc.HAS_SSL and tools.config['secure']):
227                 logger.notifyChannel("web-services", netsvc.LOG_INFO, "You are not using the SSL layer")
228         else:
229                 logger.notifyChannel("web-services", netsvc.LOG_INFO, "You are using the SSL Layer")
230
231 if tools.config['netrpc']:
232         try:
233                 netport = int(tools.config["netport"])
234         except Exception:
235                 logger.notifyChannel("init", netsvc.LOG_ERROR, "invalid port '%s'!" % (tools.config["netport"],))
236                 sys.exit(1)
237         netinterface = tools.config["netinterface"]
238         
239         tinySocket = netsvc.TinySocketServerThread(netinterface, netport, False)
240         logger.notifyChannel("web-services", netsvc.LOG_INFO, "starting netrpc service, port "+str(netport))
241
242 def handler(signum, frame):
243         from tools import config
244         if tools.config['netrpc']:
245                 tinySocket.stop()
246         if tools.config['xmlrpc']:
247                 httpd.stop()
248         netsvc.Agent.quit()
249         if config['pidfile']:
250                 os.unlink(config['pidfile'])
251         sys.exit(0)
252
253 from tools import config
254 if config['pidfile']:
255         fd=open(config['pidfile'], 'w')
256         pidtext="%d" % (os.getpid())
257         fd.write(pidtext)
258         fd.close()
259
260 signal.signal(signal.SIGINT, handler)
261 signal.signal(signal.SIGTERM, handler)
262
263 logger.notifyChannel("web-services", netsvc.LOG_INFO, 'the server is running, waiting for connections...')
264 if tools.config['netrpc']:
265         tinySocket.start()
266 if tools.config['xmlrpc']:
267         httpd.start()
268 #dispatcher.run()
269
270 while True:
271         time.sleep(1)