[MERGE] Merge with trunk

bzr revid: fme@openerp.com-20110829152720-055wnqlm6vbfl7ta
This commit is contained in:
Fabien Meghazi
2011-08-29 17:27:20 +02:00
39 changed files with 242 additions and 315 deletions
+159 -127
View File
@@ -30,9 +30,6 @@ GNU Public Licence.
(c) 2003-TODAY, Fabien Pinckaers - OpenERP s.a.
"""
#----------------------------------------------------------
# python imports
#----------------------------------------------------------
import logging
import os
import signal
@@ -45,139 +42,140 @@ import openerp
__author__ = openerp.release.author
__version__ = openerp.release.version
if os.name == 'posix':
import pwd
# We DON't log this using the standard logger, because we might mess
# with the logfile's permissions. Just do a quick exit here.
if pwd.getpwuid(os.getuid())[0] == 'root' :
sys.stderr.write("Attempted to run OpenERP server as root. This is not good, aborting.\n")
def check_root_user():
""" Exit if the process's user is 'root' (on POSIX system)."""
if os.name == 'posix':
import pwd
if pwd.getpwuid(os.getuid())[0] == 'root' :
sys.stderr.write("Running as user 'root' is a security risk, aborting.\n")
sys.exit(1)
def check_postgres_user():
""" Exit if the configured database user is 'postgres'.
This function assumes the configuration has been initialized.
"""
config = openerp.tools.config
if config['db_user'] == 'postgres':
sys.stderr.write("Using the database user 'postgres' is a security risk, aborting.")
sys.exit(1)
#-----------------------------------------------------------------------
# parse the command line
#-----------------------------------------------------------------------
openerp.tools.config.parse_config(sys.argv[1:])
config = openerp.tools.config
def report_configuration():
""" Log the server version and some configuration values.
#----------------------------------------------------------
# get logger
#----------------------------------------------------------
openerp.netsvc.init_logger()
logger = logging.getLogger('server')
This function assumes the configuration has been initialized.
"""
config = openerp.tools.config
logger = logging.getLogger('server')
logger.info("OpenERP version %s", __version__)
for name, value in [('addons paths', config['addons_path']),
('database hostname', config['db_host'] or 'localhost'),
('database port', config['db_port'] or '5432'),
('database user', config['db_user'])]:
logger.info("%s: %s", name, value)
logger.info("OpenERP version - %s", __version__)
for name, value in [('addons_path', config['addons_path']),
('database hostname', config['db_host'] or 'localhost'),
('database port', config['db_port'] or '5432'),
('database user', config['db_user'])]:
logger.info("%s - %s", name, value)
def setup_pid_file():
""" Create a file with the process id written in it.
# Don't allow if the connection to PostgreSQL done by postgres user
if config['db_user'] == 'postgres':
logger.error("Connecting to the database as 'postgres' user is forbidden, as it present major security issues. Shutting down.")
sys.exit(1)
This function assumes the configuration has been initialized.
"""
config = openerp.tools.config
if config['pidfile']:
fd = open(config['pidfile'], 'w')
pidtext = "%d" % (os.getpid())
fd.write(pidtext)
fd.close()
#----------------------------------------------------------
# init net service
#----------------------------------------------------------
logger.info('initialising distributed objects services')
def preload_registry(dbname):
""" Preload a registry, and start the cron."""
db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
pool.get('ir.cron').restart(db.dbname)
#----------------------------------------------------------
# Load and update databases if requested
#----------------------------------------------------------
def run_test_file(dbname, test_file):
""" Preload a registry, possibly run a test file, and start the cron."""
db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
if not ( config["stop_after_init"] or \
config["translate_in"] or \
config["translate_out"] ):
openerp.osv.osv.start_object_proxy()
openerp.service.web_services.start_web_services()
cr = db.cursor()
logger = logging.getLogger('server')
logger.info('loading test file %s', test_file)
openerp.tools.convert_yaml_import(cr, 'base', file(test_file), {}, 'test', True)
cr.rollback()
cr.close()
def export_translation():
config = openerp.tools.config
dbname = config['db_name']
logger = logging.getLogger('server')
if config["language"]:
msg = "language %s" % (config["language"],)
else:
msg = "new language"
logger.info('writing translation file for %s to %s', msg,
config["translate_out"])
fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
buf = file(config["translate_out"], "w")
cr = openerp.pooler.get_db(dbname).cursor()
openerp.tools.trans_export(config["language"],
config["translate_modules"] or ["all"], buf, fileformat, cr)
cr.close()
buf.close()
logger.info('translation file written successfully')
def import_translation():
config = openerp.tools.config
context = {'overwrite': config["overwrite_existing_translations"]}
dbname = config['db_name']
cr = openerp.pooler.get_db(dbname).cursor()
openerp.tools.trans_load( cr, config["translate_in"], config["language"],
context=context)
openerp.tools.trans_update_res_ids(cr)
cr.commit()
cr.close()
def start_services():
http_server = openerp.service.http_server
netrpc_server = openerp.service.netrpc_server
# Instantiate local services (this is a legacy design).
openerp.osv.osv.start_object_proxy()
# Export (for RPC) services.
openerp.service.web_services.start_web_services()
# Initialize the HTTP stack.
http_server.init_servers()
http_server.init_xmlrpc()
http_server.init_static_http()
netrpc_server.init_servers()
if config['db_name']:
for dbname in config['db_name'].split(','):
db, pool = openerp.pooler.get_db_and_pool(dbname, update_module=config['init'] or config['update'], pooljobs=False)
cr = db.cursor()
# Start the main cron thread.
openerp.netsvc.start_agent()
if config["test_file"]:
logger.info('loading test file %s', config["test_file"])
openerp.tools.convert_yaml_import(cr, 'base', file(config["test_file"]), {}, 'test', True)
cr.rollback()
pool.get('ir.cron').restart(db.dbname)
cr.close()
#----------------------------------------------------------
# translation stuff
#----------------------------------------------------------
if config["translate_out"]:
if config["language"]:
msg = "language %s" % (config["language"],)
else:
msg = "new language"
logger.info('writing translation file for %s to %s', msg, config["translate_out"])
fileformat = os.path.splitext(config["translate_out"])[-1][1:].lower()
buf = file(config["translate_out"], "w")
dbname = config['db_name']
cr = openerp.pooler.get_db(dbname).cursor()
openerp.tools.trans_export(config["language"], config["translate_modules"] or ["all"], buf, fileformat, cr)
cr.close()
buf.close()
logger.info('translation file written successfully')
sys.exit(0)
if config["translate_in"]:
context = {'overwrite': config["overwrite_existing_translations"]}
dbname = config['db_name']
cr = openerp.pooler.get_db(dbname).cursor()
openerp.tools.trans_load(cr,
config["translate_in"],
config["language"],
context=context)
openerp.tools.trans_update_res_ids(cr)
cr.commit()
cr.close()
sys.exit(0)
#----------------------------------------------------------------------------------
# if we don't want the server to continue to run after initialization, we quit here
#----------------------------------------------------------------------------------
if config["stop_after_init"]:
sys.exit(0)
openerp.netsvc.start_agent()
#----------------------------------------------------------
# Launch Servers
#----------------------------------------------------------
LST_SIGNALS = ['SIGINT', 'SIGTERM']
SIGNALS = dict(
[(getattr(signal, sign), sign) for sign in LST_SIGNALS]
)
# Start the top-level servers threads (normally HTTP, HTTPS, and NETRPC).
openerp.netsvc.Server.startAll()
# Variable keeping track of the number of calls to the signal handler defined
# below. This variable is monitored by ``quit_on_signals()``.
quit_signals_received = 0
def handler(signum, frame):
"""
:param signum: the signal number
def signal_handler(sig, frame):
""" Signal handler: exit ungracefully on the second handled signal.
:param sig: the signal number
:param frame: the interrupted stack frame or None
"""
global quit_signals_received
quit_signals_received += 1
if quit_signals_received > 1:
# logging.shutdown was already called at this point.
sys.stderr.write("Forced shutdown.\n")
os._exit(0)
def dumpstacks(signum, frame):
def dumpstacks(sig, frame):
""" Signal handler: dump a stack trace for each existing thread."""
# code from http://stackoverflow.com/questions/132058/getting-stack-trace-from-a-running-python-application#answer-2569696
# modified for python 2.5 compatibility
thread_map = dict(threading._active, **threading._limbo)
@@ -191,20 +189,33 @@ def dumpstacks(signum, frame):
code.append(" %s" % (line.strip()))
logging.getLogger('dumpstacks').info("\n".join(code))
for signum in SIGNALS:
signal.signal(signum, handler)
def setup_signal_handlers():
""" Register the signal handler defined above. """
SIGNALS = map(lambda x: getattr(signal, "SIG%s" % x), "INT TERM".split())
map(lambda sig: signal.signal(sig, signal_handler), SIGNALS)
if os.name == 'posix':
signal.signal(signal.SIGQUIT, dumpstacks)
if os.name == 'posix':
signal.signal(signal.SIGQUIT, dumpstacks)
def quit_on_signals():
""" Wait for one or two signals then shutdown the server.
The first SIGINT or SIGTERM signal will initiate a graceful shutdown while
a second one if any will force an immediate exit.
"""
# Wait for a first signal to be handled. (time.sleep will be interrupted
# by the signal handler.)
while quit_signals_received == 0:
time.sleep(60)
def quit():
openerp.netsvc.Agent.quit()
openerp.netsvc.Server.quitAll()
config = openerp.tools.config
if config['pidfile']:
os.unlink(config['pidfile'])
logger = logging.getLogger('shutdown')
logger.info("Initiating OpenERP Server shutdown")
logger.info("Hit CTRL-C again or send a second signal to immediately terminate the server...")
logger = logging.getLogger('server')
logger.info("Initiating shutdown")
logger.info("Hit CTRL-C again or send a second signal to force the sutdown.")
logging.shutdown()
# manually join() all threads before calling sys.exit() to allow a second signal
@@ -219,19 +230,40 @@ def quit():
time.sleep(0.05)
sys.exit(0)
if config['pidfile']:
fd = open(config['pidfile'], 'w')
pidtext = "%d" % (os.getpid())
fd.write(pidtext)
fd.close()
if __name__ == "__main__":
openerp.netsvc.Server.startAll()
check_root_user()
openerp.tools.config.parse_config(sys.argv[1:])
check_postgres_user()
openerp.netsvc.init_logger()
report_configuration()
logger.info('OpenERP server is running, waiting for connections...')
config = openerp.tools.config
while quit_signals_received == 0:
time.sleep(60)
if config["test_file"]:
run_test_file(config['db_name'], config['test_file'])
sys.exit(0)
quit()
if config["translate_out"]:
export_translation()
sys.exit(0)
if config["translate_in"]:
import_translation()
sys.exit(0)
if config['db_name']:
for dbname in config['db_name'].split(','):
preload_registry(dbname)
if config["stop_after_init"]:
sys.exit(0)
setup_pid_file()
setup_signal_handlers()
start_services()
logger = logging.getLogger('server')
logger.info('OpenERP server is running, waiting for connections...')
quit_on_signals()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
+12 -13
View File
@@ -59,18 +59,18 @@
'res/res_request_view.xml',
'res/res_lang_view.xml',
'res/res_log_view.xml',
'res/partner/partner_report.xml',
'res/partner/partner_view.xml',
'res/partner/partner_shortcut_data.xml',
'res/partner/bank_view.xml',
'res/country_view.xml',
'res/res_partner_report.xml',
'res/res_partner_view.xml',
'res/res_partner_shortcut_data.xml',
'res/res_bank_view.xml',
'res/res_country_view.xml',
'res/res_currency_view.xml',
'res/partner/crm_view.xml',
'res/partner/wizard/partner_sms_send_view.xml',
'res/partner/wizard/partner_wizard_spam_view.xml',
'res/partner/wizard/partner_clear_ids_view.xml',
'res/partner/wizard/partner_wizard_ean_check_view.xml',
'res/partner/partner_data.xml',
'res/res_partner_event_view.xml',
'res/wizard/partner_sms_send_view.xml',
'res/wizard/partner_wizard_spam_view.xml',
'res/wizard/partner_clear_ids_view.xml',
'res/wizard/partner_wizard_ean_check_view.xml',
'res/res_partner_data.xml',
'res/ir_property_view.xml',
'security/base_security.xml',
'publisher_warranty/publisher_warranty_view.xml',
@@ -81,8 +81,7 @@
],
'demo_xml': [
'base_demo.xml',
'res/partner/partner_demo.xml',
'res/partner/crm_demo.xml',
'res/res_partner_demo.xml',
'res/res_widget_demo.xml',
],
'test': [
+2 -3
View File
@@ -936,10 +936,9 @@ class act_client(osv.osv):
for record in self.browse(cr, uid, ids, context=context)
])
def _set_params(self, cr, uid, ids, field_name, field_value, arg, context):
def _set_params(self, cr, uid, id, field_name, field_value, arg, context):
assert isinstance(field_value, dict), "params can only be dictionaries"
for record in self.browse(cr, uid, ids, context=context):
record.write({field_name: repr(field_value)})
self.write(cr, uid, id, {'params_store': repr(field_value)}, context=context)
_columns = {
'tag': fields.char('Client action tag', size=64, required=True,
+10 -3
View File
@@ -21,9 +21,11 @@
import tools
import country
import res_country
import res_lang
import partner
import res_partner
import res_partner_event
import res_bank
import res_config
import res_currency
import res_company
@@ -31,6 +33,11 @@ import res_user
import res_request
import res_lang
import res_log
import ir_property
import res_widget
import ir_property
import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,34 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import tools
from partner import *
from bank import *
from crm import *
import wizard
import report
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="1">
<record model="res.partner.canal">
<field name="name">website</field>
</record>
<record model="res.partner.canal">
<field name="name">phone</field>
</record>
<record model="res.partner.canal">
<field name="name">direct</field>
</record>
<record model="res.partner.canal">
<field name="name">E-mail</field>
</record>
</data>
</openerp>
@@ -1,68 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="res_partner_canal-view-tree" model="ir.ui.view">
<field name="name">res.partner.canal.tree</field>
<field name="model">res.partner.canal</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Channels">
<field name="name" select="1"/>
<field name="active" select="1"/>
</tree>
</field>
</record>
<record id="res_partner_canal-view" model="ir.ui.view">
<field name="name">res.partner.canal.form</field>
<field name="model">res.partner.canal</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Channel">
<field name="name" select="1"/>
<field name="active" select="1"/>
</form>
</field>
</record>
<record id="res_partner_canal-act" model="ir.actions.act_window">
<field name="name">Channels</field>
<field name="res_model">res.partner.canal</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="help">Track from where is coming your leads and opportunities by creating specific channels that will be maintained at the creation of a document in the system. Some examples of channels can be: Website, Phone Call, Reseller, etc.</field>
</record>
<!-- <menuitem id="menu_partner_events" name="Events" parent="menu_config_address_book" sequence="7"/>-->
<menuitem id="base.menu_crm_config_lead" name="Leads &amp; Opportunities"
parent="base.menu_base_config" sequence="2" groups="base.group_extended"/>
<menuitem action="res_partner_canal-act" id="menu_res_partner_canal-act" parent="base.menu_crm_config_lead" sequence="4"/>
<record id="res_partner_event-wopartner-view_form" model="ir.ui.view">
<field name="name">res.partner.event.form</field>
<field name="model">res.partner.event</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Event Logs">
<separator colspan="4" string="General Description"/>
<field name="name" select="1" string="Name"/>
<field name="date" select="1"/>
<field name="user_id" select="1"/>
<separator colspan="4" string="Description"/>
<field colspan="4" name="description" nolabel="1"/>
</form>
</field>
</record>
<record id="res_partner_event-wopartner-view_tree" model="ir.ui.view">
<field name="name">res.partner.event.tree</field>
<field name="model">res.partner.event</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Event Logs">
<field name="date"/>
<field name="name" string="Event"/>
<field name="user_id"/>
</tree>
</field>
</record>
</data>
</openerp>
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<report id="res_partner_address_report" model="res.partner" name="res.partner.address" string="Labels" xml="base/res/partner/report/partner_address.xml" xsl="base/res/partner/report/partner_address.xsl" groups="base.group_extended"/>
<!--
<report string="Business Cards" model="res.partner" name="res.partner.businesscard" xml="base/res/partner/report/business_card.xml" xsl="base/res/partner/report/business_card.xsl"/>
-->
</data>
</openerp>
@@ -23,22 +23,6 @@ import time
from osv import osv
from osv import fields
#
# Sale/Purchase Canal, Media
#
class res_partner_canal(osv.osv):
_name = "res.partner.canal"
_description = "Channels"
_order = 'name'
_columns = {
'name': fields.char('Channel Name', size=64, required=True),
'active': fields.boolean('Active'),
}
_defaults = {
'active': lambda *a: 1,
}
res_partner_canal()
class res_partner_event(osv.osv):
_name = "res.partner.event"
_columns = {
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- <menuitem id="menu_partner_events" name="Events" parent="menu_config_address_book" sequence="7"/>-->
<record id="res_partner_event-wopartner-view_form" model="ir.ui.view">
<field name="name">res.partner.event.form</field>
<field name="model">res.partner.event</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Event Logs">
<separator colspan="4" string="General Description"/>
<field name="name" select="1" string="Name"/>
<field name="date" select="1"/>
<field name="user_id" select="1"/>
<separator colspan="4" string="Description"/>
<field colspan="4" name="description" nolabel="1"/>
</form>
</field>
</record>
<record id="res_partner_event-wopartner-view_tree" model="ir.ui.view">
<field name="name">res.partner.event.tree</field>
<field name="model">res.partner.event</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Event Logs">
<field name="date"/>
<field name="name" string="Event"/>
<field name="user_id"/>
</tree>
</field>
</record>
</data>
</openerp>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<report id="res_partner_address_report" model="res.partner" name="res.partner.address" string="Labels" xml="base/res/report/partner_address.xml" xsl="base/res/report/partner_address.xsl" groups="base.group_extended"/>
<!--
<report string="Business Cards" model="res.partner" name="res.partner.businesscard" xml="base/res/report/business_card.xml" xsl="base/res/report/business_card.xsl"/>
-->
</data>
</openerp>
@@ -518,7 +518,7 @@
<field name="help">Manage the partner categories in order to better classify them for tracking and analysis purposes. A partner may belong to several categories and categories have a hierarchy structure: a partner belonging to a category also belong to his parent category.</field>
</record>
<menuitem action="action_partner_category_form" id="menu_partner_category_form" name="Partner Categories" sequence="4" parent="menu_config_address_book"/>
<menuitem action="action_partner_category_form" id="menu_partner_category_form" name="Partner Categories" sequence="4" parent="menu_config_address_book" groups="base.group_extended"/>
<act_window domain="[('partner_id', '=', active_id)]" context="{'default_partner_id':active_id}"
id="act_res_partner_event" name="Events"
@@ -64,8 +64,6 @@
"access_res_partner_bank_type_group_user","res_partner_bank_type group_user","model_res_partner_bank_type",,1,0,0,0
"access_res_partner_bank_type_field_group_partner_manager","res_partner_bank_type_field group_partner_manager","model_res_partner_bank_type_field","group_partner_manager",1,1,1,1
"access_res_partner_bank_type_field_group_user","res_partner_bank_type_field group_user","model_res_partner_bank_type_field",,1,0,0,0
"access_res_partner_canal_group_user","res_partner_canal group_user","model_res_partner_canal","group_user",1,0,0,0
"access_res_partner_canal_group_partner_manager","res_partner_canal group_partner_manager","model_res_partner_canal","group_partner_manager",1,1,1,1
"access_res_partner_category_group_user","res_partner_category group_user","model_res_partner_category","group_user",1,0,0,0
"access_res_partner_category_group_partner_manager","res_partner_category group_partner_manager","model_res_partner_category","group_partner_manager",1,1,1,1
"access_res_partner_event_group_user","res_partner_event group_user","model_res_partner_event","group_user",1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
64 access_res_partner_bank_type_group_user res_partner_bank_type group_user model_res_partner_bank_type 1 0 0 0
65 access_res_partner_bank_type_field_group_partner_manager res_partner_bank_type_field group_partner_manager model_res_partner_bank_type_field group_partner_manager 1 1 1 1
66 access_res_partner_bank_type_field_group_user res_partner_bank_type_field group_user model_res_partner_bank_type_field 1 0 0 0
access_res_partner_canal_group_user res_partner_canal group_user model_res_partner_canal group_user 1 0 0 0
access_res_partner_canal_group_partner_manager res_partner_canal group_partner_manager model_res_partner_canal group_partner_manager 1 1 1 1
67 access_res_partner_category_group_user res_partner_category group_user model_res_partner_category group_user 1 0 0 0
68 access_res_partner_category_group_partner_manager res_partner_category group_partner_manager model_res_partner_category group_partner_manager 1 1 1 1
69 access_res_partner_event_group_user res_partner_event group_user model_res_partner_event group_user 1 0 0 0
+3 -8
View File
@@ -70,15 +70,10 @@ class Registry(object):
res = []
# Instanciate classes registered through their constructor and
# add them to the pool.
for klass in openerp.osv.orm.module_class_list.get(module, []):
res.append(klass.createInstance(self, cr))
# Instanciate classes automatically discovered.
# Instantiate registered classes (via metamodel discovery or via explicit
# constructor call), and add them to the pool.
for cls in openerp.osv.orm.MetaModel.module_to_models.get(module, []):
if cls not in openerp.osv.orm.module_class_list.get(module, []):
res.append(cls.createInstance(self, cr))
res.append(cls.createInstance(self, cr))
return res
+2 -1
View File
@@ -852,12 +852,13 @@ class function(_column):
This callable implements the write operation for the function field
and must have the following signature:
.. function:: fnct_inv(model, cr, uid, ids, field_name, field_value, fnct_inv_arg, context)
.. function:: fnct_inv(model, cr, uid, id, field_name, field_value, fnct_inv_arg, context)
Callable that implements the ``write`` operation for the function field.
:param orm_template model: model to which the field belongs (should be ``self`` for
a model method)
:param int id: the identifier of the object to write on
:param str field_name: name of the field to set
:param fnct_inv_arg: arbitrary value passed when declaring the function field
:return: True
+6 -11
View File
@@ -70,9 +70,6 @@ from openerp.tools import SKIPPED_ELEMENT_TYPES
regex_order = re.compile('^(([a-z0-9_]+|"[a-z0-9_]+")( *desc| *asc)?( *, *|))+$', re.I)
regex_object_name = re.compile(r'^[a-z0-9_.]+$')
# Mapping between openerp module names and their osv classes.
module_class_list = {}
# Super-user identifier (aka Administrator aka root)
ROOT_USER_ID = 1
@@ -806,23 +803,21 @@ class orm_template(object):
return obj
def __new__(cls):
""" Register this model.
"""Register this model.
This doesn't create an instance but simply register the model
as being part of the module where it is defined.
TODO make it possible to not even have to call the constructor
to be registered.
"""
# Set the module name (e.g. base, sale, accounting, ...) on the class.
module = cls.__module__.split('.')[0]
if not hasattr(cls, '_module'):
cls._module = module
# Remember which models to instanciate for this module.
module_class_list.setdefault(cls._module, []).append(cls)
# Record this class in the list of models to instantiate for this module,
# managed by the metaclass.
module_model_list = MetaModel.module_to_models.setdefault(cls._module, [])
if cls not in module_model_list:
module_model_list.append(cls)
# Since we don't return an instance here, the __init__
# method won't be called.
+2 -1
View File
@@ -458,7 +458,8 @@ def trans_export(lang, modules, buffer, format, cr):
tar.close()
else:
raise Exception(_('Bad file format'))
raise Exception(_('Unrecognized extension: must be one of '
'.csv, .po, or .tgz (received .%s).' % format))
newlang = not bool(lang)
if newlang: