~therp-nl/ocb-server/6.1-lp1175516-expression_search_translations_with_fallback_on_untranslated

1844.8.2 by Xavier Morel
Fix server start shebang: hardcoding /usr/bin/python bypasses virtualenv (or other), /usr/bin/env python doesn't
1
#!/usr/bin/env python
1864 by pap(openerp)
Changed encoding to coding ref: PEP: 0263
2
# -*- coding: utf-8 -*-
1 by pinky
New trunk
3
##############################################################################
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
4
#
1861 by PSO(OpenERP)
Changed licencing
5
#    OpenERP, Open Source Management Solution
6
#    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
1230 by Christophe Simonis
passing in GPL-3
7
#
8
#    This program is free software: you can redistribute it and/or modify
1861 by PSO(OpenERP)
Changed licencing
9
#    it under the terms of the GNU Affero General Public License as
10
#    published by the Free Software Foundation, either version 3 of the
11
#    License, or (at your option) any later version.
1230 by Christophe Simonis
passing in GPL-3
12
#
13
#    This program is distributed in the hope that it will be useful,
14
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1861 by PSO(OpenERP)
Changed licencing
16
#    GNU Affero General Public License for more details.
1230 by Christophe Simonis
passing in GPL-3
17
#
1861 by PSO(OpenERP)
Changed licencing
18
#    You should have received a copy of the GNU Affero General Public License
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
19
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
1230 by Christophe Simonis
passing in GPL-3
20
#
21
##############################################################################
1 by pinky
New trunk
22
23
"""
1072 by Stephane Wirtel
Rename Tiny ERP to OpenERP
24
OpenERP - Server
25
OpenERP is an ERP+CRM program for small and medium businesses.
1 by pinky
New trunk
26
27
The whole source code is distributed under the terms of the
28
GNU Public Licence.
29
3611 by Fabien Pinckaers
nope
30
(c) 2003-TODAY, Fabien Pinckaers - OpenERP SA
1 by pinky
New trunk
31
"""
32
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
33
import imp
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
34
import logging
1517 by Stephane Wirtel
[IMP] PEP8
35
import os
36
import signal
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
37
import sys
38
import threading
39
import traceback
3417.6.2 by Vo Minh Thu
[REF] openerp-server: cleaned imports.
40
import time
1089 by Christophe Simonis
fix conflict between oldxml and the xml package used or defined in bzrlib
41
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
42
import openerp
43
__author__ = openerp.release.author
44
__version__ = openerp.release.version
1089 by Christophe Simonis
fix conflict between oldxml and the xml package used or defined in bzrlib
45
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
46
# Also use the `openerp` logger for the main script.
47
_logger = logging.getLogger('openerp')
3943.1.1 by Vo Minh Thu
[IMP] modules: began to replace sys.path appending with an import hook.
48
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
49
def check_root_user():
3554 by Vo Minh Thu
[FIX] openerp-server: forgot to remove the utf-8 quote as stated on the merge prop by xrg.
50
    """ Exit if the process's user is 'root' (on POSIX system)."""
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
51
    if os.name == 'posix':
52
        import pwd
53
        if pwd.getpwuid(os.getuid())[0] == 'root' :
54
            sys.stderr.write("Running as user 'root' is a security risk, aborting.\n")
55
            sys.exit(1)
56
57
def check_postgres_user():
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
58
    """ Exit if the configured database user is 'postgres'.
59
60
    This function assumes the configuration has been initialized.
61
    """
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
62
    config = openerp.tools.config
63
    if config['db_user'] == 'postgres':
64
        sys.stderr.write("Using the database user 'postgres' is a security risk, aborting.")
2867 by Julien Thewys
[FIX] pwd module does not exist on non posix platform (win32).
65
        sys.exit(1)
1119.1.52 by P. Christeas
Don't allow the server to run as root.
66
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
67
def report_configuration():
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
68
    """ Log the server version and some configuration values.
69
70
    This function assumes the configuration has been initialized.
71
    """
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
72
    config = openerp.tools.config
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
73
    _logger.info("OpenERP version %s", __version__)
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
74
    for name, value in [('addons paths', config['addons_path']),
75
                        ('database hostname', config['db_host'] or 'localhost'),
76
                        ('database port', config['db_port'] or '5432'),
77
                        ('database user', config['db_user'])]:
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
78
        _logger.info("%s: %s", name, value)
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
79
80
def setup_pid_file():
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
81
    """ Create a file with the process id written in it.
82
83
    This function assumes the configuration has been initialized.
84
    """
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
85
    config = openerp.tools.config
86
    if config['pidfile']:
87
        fd = open(config['pidfile'], 'w')
88
        pidtext = "%d" % (os.getpid())
89
        fd.write(pidtext)
90
        fd.close()
91
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
92
def preload_registry(dbname):
93
    """ Preload a registry, and start the cron."""
3645 by Olivier Dony
[IMP] openerp-server: catch db init errors to avoid exiting main thread
94
    try:
3496.3.19 by Olivier Dony
[MERGE] sync with latest trunk
95
        db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
4127.1.6 by Vo Minh Thu
[IMP] cron: re-enabled thread cron (was unnecessarilly removed in a previous commit).
96
97
        # jobs will start to be processed later, when openerp.cron.start_master_thread() is called by openerp.service.start_services()
98
        registry.schedule_cron_jobs()
3645 by Olivier Dony
[IMP] openerp-server: catch db init errors to avoid exiting main thread
99
    except Exception:
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
100
        _logger.exception('Failed to initialize database `%s`.', dbname)
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
101
102
def run_test_file(dbname, test_file):
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
103
    """ Preload a registry, possibly run a test file, and start the cron."""
3660 by Olivier Dony
[IMP] openerp-server: handle more startup exceptions w/o exiting main thread
104
    try:
3496.3.5 by Vo Minh Thu
[IMP] registry: whene deleting a registry, also delete its cache and cron.
105
        db, registry = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
3660 by Olivier Dony
[IMP] openerp-server: handle more startup exceptions w/o exiting main thread
106
        cr = db.cursor()
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
107
        _logger.info('loading test file %s', test_file)
3660 by Olivier Dony
[IMP] openerp-server: handle more startup exceptions w/o exiting main thread
108
        openerp.tools.convert_yaml_import(cr, 'base', file(test_file), {}, 'test', True)
109
        cr.rollback()
110
        cr.close()
111
    except Exception:
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
112
        _logger.exception('Failed to initialize database `%s` and run test file `%s`.', dbname, test_file)
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
113
114
115
def export_translation():
116
    config = openerp.tools.config
117
    dbname = config['db_name']
118
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
119
    if config["language"]:
120
        msg = "language %s" % (config["language"],)
990 by Christophe Simonis
* allow export of translation po files into a tgz archive.
121
    else:
122
        msg = "new language"
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
123
    _logger.info('writing translation file for %s to %s', msg,
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
124
        config["translate_out"])
922 by Christophe Simonis
convert tabs to 4 spaces
125
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
126
    fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
127
    buf = file(config["translate_out"], "w")
128
    cr = openerp.pooler.get_db(dbname).cursor()
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
129
    openerp.tools.trans_export(config["language"],
130
        config["translate_modules"] or ["all"], buf, fileformat, cr)
3213.1.1 by Vo Minh Thu
[IMP] trans_export/trans_load: passing a cursor around instead of a dbname.
131
    cr.close()
922 by Christophe Simonis
convert tabs to 4 spaces
132
    buf.close()
957 by Olivier Laurent
pep8
133
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
134
    _logger.info('translation file written successfully')
1 by pinky
New trunk
135
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
136
def import_translation():
137
    config = openerp.tools.config
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
138
    context = {'overwrite': config["overwrite_existing_translations"]}
139
    dbname = config['db_name']
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
140
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
141
    cr = openerp.pooler.get_db(dbname).cursor()
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
142
    openerp.tools.trans_load( cr, config["translate_in"], config["language"],
143
        context=context)
3213.1.1 by Vo Minh Thu
[IMP] trans_export/trans_load: passing a cursor around instead of a dbname.
144
    cr.commit()
145
    cr.close()
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
146
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
147
# Variable keeping track of the number of calls to the signal handler defined
148
# below. This variable is monitored by ``quit_on_signals()``.
3417.6.2 by Vo Minh Thu
[REF] openerp-server: cleaned imports.
149
quit_signals_received = 0
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
150
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
151
def signal_handler(sig, frame):
152
    """ Signal handler: exit ungracefully on the second handled signal.
153
154
    :param sig: the signal number
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
155
    :param frame: the interrupted stack frame or None
1496 by Stephane Wirtel
[IMP] Refactoring, resulting from pylint
156
    """
3417.6.2 by Vo Minh Thu
[REF] openerp-server: cleaned imports.
157
    global quit_signals_received
158
    quit_signals_received += 1
159
    if quit_signals_received > 1:
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
160
        # logging.shutdown was already called at this point.
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
161
        sys.stderr.write("Forced shutdown.\n")
162
        os._exit(0)
163
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
164
def dumpstacks(sig, frame):
165
    """ Signal handler: dump a stack trace for each existing thread."""
2751 by Christophe Simonis
[IMP] kill -SIGQUIT dumps the stack of all threads (forwardport of 2124 chs@openerp.com-20100920165253-esaatbgtvha9jhb9 from 5.0 branch)
166
    # code from http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application#answer-2569696
2780 by Olivier Dony
[FIX] openerp-server.py: python 2.5 compatibility for thread dump
167
    # modified for python 2.5 compatibility
168
    thread_map = dict(threading._active, **threading._limbo)
169
    id2name = dict([(threadId, thread.getName()) for threadId, thread in thread_map.items()])
2751 by Christophe Simonis
[IMP] kill -SIGQUIT dumps the stack of all threads (forwardport of 2124 chs@openerp.com-20100920165253-esaatbgtvha9jhb9 from 5.0 branch)
170
    code = []
171
    for threadId, stack in sys._current_frames().items():
4104 by Olivier Dony
[FIX] openerp-server: allow missing thread names in dump_stacks
172
        code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,'n/a'), threadId))
2751 by Christophe Simonis
[IMP] kill -SIGQUIT dumps the stack of all threads (forwardport of 2124 chs@openerp.com-20100920165253-esaatbgtvha9jhb9 from 5.0 branch)
173
        for filename, lineno, name, line in traceback.extract_stack(stack):
174
            code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
175
            if line:
176
                code.append("  %s" % (line.strip()))
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
177
    _logger.info("\n".join(code))
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
178
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
179
def setup_signal_handlers():
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
180
    """ Register the signal handler defined above. """
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
181
    SIGNALS = map(lambda x: getattr(signal, "SIG%s" % x), "INT TERM".split())
182
    if os.name == 'posix':
3788.1.1 by Vo Minh Thu
[FIX] Hitting ^C on Windows is broken, this patch
183
        map(lambda sig: signal.signal(sig, signal_handler), SIGNALS)
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
184
        signal.signal(signal.SIGQUIT, dumpstacks)
3788.1.1 by Vo Minh Thu
[FIX] Hitting ^C on Windows is broken, this patch
185
    elif os.name == 'nt':
186
        import win32api
187
        win32api.SetConsoleCtrlHandler(lambda sig: signal_handler(sig, None), 1)
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
188
189
def quit_on_signals():
190
    """ Wait for one or two signals then shutdown the server.
191
192
    The first SIGINT or SIGTERM signal will initiate a graceful shutdown while
193
    a second one if any will force an immediate exit.
194
195
    """
196
    # Wait for a first signal to be handled. (time.sleep will be interrupted
3788.1.1 by Vo Minh Thu
[FIX] Hitting ^C on Windows is broken, this patch
197
    # by the signal handler.) The try/except is for the win32 case.
198
    try:
199
        while quit_signals_received == 0:
200
            time.sleep(60)
201
    except KeyboardInterrupt, e:
202
        pass
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
203
3417.6.3 by Vo Minh Thu
[REF] openerp-server: better imports.
204
    if config['pidfile']:
205
        os.unlink(config['pidfile'])
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
206
3644.1.1 by Vo Minh Thu
[IMP] tests: added a simple test case to create a database via XML-RPC.
207
    openerp.service.stop_services()
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
208
    sys.exit(0)
209
4052.1.1 by Stephane Wirtel
[FIX] babel: Set the right path for the localedata of Babel when we use it via the py2exe app.
210
def configure_babel_localedata_path():
211
    # Workaround: py2exe and babel.
212
    if hasattr(sys, 'frozen'):
213
        import babel
214
        babel.localedata._dirname = os.path.join(os.path.dirname(sys.executable), 'localedata')
215
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
216
if __name__ == "__main__":
217
3640 by niv-openerp
[imp] switched the dates to UTC. I'm so happy.
218
    os.environ["TZ"] = "UTC"
219
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
220
    check_root_user()
221
    openerp.tools.config.parse_config(sys.argv[1:])
3943.1.1 by Vo Minh Thu
[IMP] modules: began to replace sys.path appending with an import hook.
222
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
223
    check_postgres_user()
224
    openerp.netsvc.init_logger()
225
    report_configuration()
226
227
    config = openerp.tools.config
228
4052.1.1 by Stephane Wirtel
[FIX] babel: Set the right path for the localedata of Babel when we use it via the py2exe app.
229
    configure_babel_localedata_path()
230
3585 by Olivier Dony
[IMP] openerp-server: setup signal handlers earlier, spellcheck
231
    setup_signal_handlers()
232
3549.1.2 by Vo Minh Thu
[REF] openerp-server: separated the --test-file mechanism from the main code path.
233
    if config["test_file"]:
234
        run_test_file(config['db_name'], config['test_file'])
235
        sys.exit(0)
236
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
237
    if config["translate_out"]:
238
        export_translation()
239
        sys.exit(0)
240
241
    if config["translate_in"]:
242
        import_translation()
243
        sys.exit(0)
244
3571 by Vo Minh Thu
[FIX] startup: when preloading a registry with the -d option, document_webdav
245
    if not config["stop_after_init"]:
246
        # Some module register themselves when they are loaded so we need the
247
        # services to be running before loading any registry.
3644.1.1 by Vo Minh Thu
[IMP] tests: added a simple test case to create a database via XML-RPC.
248
        openerp.service.start_services()
3571 by Vo Minh Thu
[FIX] startup: when preloading a registry with the -d option, document_webdav
249
3521.1.17 by Vo Minh Thu
[IMP] wsgi: modules can be pre-loaded and expose a WSGI handler.
250
    for m in openerp.conf.server_wide_modules:
3660 by Olivier Dony
[IMP] openerp-server: handle more startup exceptions w/o exiting main thread
251
        try:
4028.1.2 by Vo Minh Thu
[IMP] post_load: factored common code. This also fix bug lp:929466
252
            openerp.modules.module.load_openerp_module(m)
3660 by Olivier Dony
[IMP] openerp-server: handle more startup exceptions w/o exiting main thread
253
        except Exception:
3740 by Vo Minh Thu
[IMP] startup script: added little reminder when the `web` module can not be imported.
254
            msg = ''
255
            if m == 'web':
256
                msg = """
257
The `web` module is provided by the addons found in the `openerp-web` project.
258
Maybe you forgot to add those addons in your addons_path configuration."""
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
259
            _logger.exception('Failed to load server-wide module `%s`.%s', m, msg)
3521.1.17 by Vo Minh Thu
[IMP] wsgi: modules can be pre-loaded and expose a WSGI handler.
260
3741 by Vo Minh Thu
[IMP] openerp-server: start services, load any server-wide module, then preload some registries.
261
    if config['db_name']:
262
        for dbname in config['db_name'].split(','):
263
            preload_registry(dbname)
264
265
    if config["stop_after_init"]:
266
        sys.exit(0)
267
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
268
    setup_pid_file()
3976.1.3 by Vo Minh Thu
[IMP] openerp-server: use a global (at the module level) _logger.
269
    _logger.info('OpenERP server is running, waiting for connections...')
3549.1.1 by Vo Minh Thu
[REF] openerp-server: streamlining startup script.
270
    quit_on_signals()
2763 by Olivier Dony
[IMP] openerp-server.py: cleanup + double CTRL-C can now be used to force immediate shutdown of server
271
923 by Christophe Simonis
add encoding comment and vim comment
272
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: