From 2d58fc61e28d07f9b63df5a2ba9e2c88e1e20425 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Fri, 30 Jan 2009 13:52:39 +0100 Subject: [PATCH 01/12] [FIX] Set the template0 as default template when you create a new database http://www.postgresql.org/docs/8.2/static/manage-ag-templatedbs.html http://www.postgresql.org/docs/8.2/static/app-pgrestore.html Thank you to Christophe Chauvet (SYLEAM) for this fix. bzr revid: stephane@tinyerp.com-20090130125239-4h8agooloymfjy0m --- bin/service/web_services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/service/web_services.py b/bin/service/web_services.py index 44c853a6d4b..53936d202f5 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -204,7 +204,7 @@ class db(netsvc.Service): cr = db.cursor() cr.autocommit(True) try: - cr.execute('CREATE DATABASE "%s" ENCODING \'unicode\'' % db_name) + cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE 'template0'""" % db_name) finally: cr.close() sql_db.close_db('template1') From 5e0e53690662c704955ea41787e758703e4d08f7 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Fri, 30 Jan 2009 16:19:03 +0100 Subject: [PATCH 02/12] [FIX] generate the pyc for redhat lp bug: https://launchpad.net/bugs/311981 fixed bzr revid: stephane@tinyerp.com-20090130151903-nggkdf0iord5o0g3 --- rpminstall_sh.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/rpminstall_sh.txt b/rpminstall_sh.txt index 5694f250b5d..bb7bb3fc10c 100644 --- a/rpminstall_sh.txt +++ b/rpminstall_sh.txt @@ -7,6 +7,7 @@ # Need to overwrite the install-part of the RPM to append the # compression-suffix onto the filenames for the man-pages. # +python -c "import compileall, os; compileall.compile_dir(os.path.join(os.environ['PWD'], 'doc'), force=True)" python -O -c "import compileall, os; compileall.compile_dir(os.path.join(os.environ['PWD'], 'doc'), force=True)" python setup.py install --optimize 1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES From 8a3a776bbdec771e1f39814bbea57d2a62176485 Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Fri, 30 Jan 2009 16:31:01 +0100 Subject: [PATCH 03/12] [FIX] Don't use the color if we use the logfile as logger bzr revid: stephane@tinyerp.com-20090130153101-94qlxou5fq8bcp0t --- bin/netsvc.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/netsvc.py b/bin/netsvc.py index e4df96a2b0d..59e56937184 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -127,7 +127,7 @@ def init_logger(): logger.addHandler(handler) logger.setLevel(tools.config['log_level'] or '0') - if isinstance(handler, logging.StreamHandler) and os.name != 'nt': + if handler is logging.StreamHandler and os.name != 'nt': # change color of level names # uses of ANSI color codes # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html From 27240361ca5ead2597ae8f0c63043bab0e969001 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Fri, 30 Jan 2009 17:55:51 +0100 Subject: [PATCH 04/12] [FIX] reactive the colored logging bzr revid: christophe@tinyerp.com-20090130165551-7e6nnn6f2xxabijd --- bin/netsvc.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/bin/netsvc.py b/bin/netsvc.py index 59e56937184..b9e4a589fab 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -93,7 +93,8 @@ def init_logger(): logger = logging.getLogger() # create a format for log messages and dates formatter = logging.Formatter('[%(asctime)s] %(levelname)s:%(name)s:%(message)s', '%a %b %d %Y %H:%M:%S') - + + logging_to_stdout = False if tools.config['syslog']: # SysLog Handler if os.name == 'nt': @@ -113,11 +114,13 @@ def init_logger(): os.makedirs(dirname) handler = logging.handlers.TimedRotatingFileHandler(logf,'D',1,30) except Exception, ex: - sys.stderr.write("ERROR: couldn't create the logfile directory\n") - handler = logging.StreamHandler(sys.stdout) + sys.stderr.write("ERROR: couldn't create the logfile directory. Logging to the standard output.\n") + handler = logging.StreamHandler(sys.stdout) + logging_to_stdout = True else: # Normal Handler on standard output handler = logging.StreamHandler(sys.stdout) + logging_to_stdout = True # tell the handler to use this format @@ -127,7 +130,7 @@ def init_logger(): logger.addHandler(handler) logger.setLevel(tools.config['log_level'] or '0') - if handler is logging.StreamHandler and os.name != 'nt': + if logging_to_stdout and os.name != 'nt': # change color of level names # uses of ANSI color codes # see http://pueblo.sourceforge.net/doc/manual/ansi_color_codes.html From 9c721d3090d41f25da4a93afcfe46822e0350224 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Sat, 31 Jan 2009 19:36:18 +0100 Subject: [PATCH 05/12] [FIX] database connections aren't serialized by default lp bug: https://launchpad.net/bugs/314449 fixed bzr revid: christophe@taupe-20090131183618-pglu86hzq3ewsfxi --- bin/service/web_services.py | 12 ++++++------ bin/sql_db.py | 11 ++++++++--- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/bin/service/web_services.py b/bin/service/web_services.py index 53936d202f5..d4b2a6e9780 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -69,9 +69,9 @@ class db(netsvc.Service): self.actions[id] = {'clean': False} db = sql_db.db_connect('template1') - cr = db.cursor() + cr = db.serialized_cursor() try: - cr.autocommit(True) + cr.autocommit(True) # XXX inhibit the effect of a serialized cursor. is it what we want ? cr.execute('CREATE DATABASE "%s" ENCODING \'unicode\'' % db_name) finally: cr.close() @@ -149,8 +149,8 @@ class db(netsvc.Service): logger = netsvc.Logger() db = sql_db.db_connect('template1') - cr = db.cursor() - cr.autocommit(True) + cr = db.serialized_cursor() + cr.autocommit(True) # XXX inhibit the effect of a serialized cursor. is it what we want ? try: try: cr.execute('DROP DATABASE "%s"' % db_name) @@ -201,8 +201,8 @@ class db(netsvc.Service): raise Exception, "Database already exists" db = sql_db.db_connect('template1') - cr = db.cursor() - cr.autocommit(True) + cr = db.serialized_cursor() + cr.autocommit(True) # XXX inhibit the effect of a serialized cursor. is it what we want ? try: cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE 'template0'""" % db_name) finally: diff --git a/bin/sql_db.py b/bin/sql_db.py index b0212ac1ea4..ff9a6b0c2c6 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -21,7 +21,7 @@ ############################################################################## import netsvc -from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_SERIALIZABLE +from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT, ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE from psycopg2.pool import ThreadedConnectionPool from psycopg2.psycopg1 import cursor as psycopg1cursor @@ -76,8 +76,9 @@ class Cursor(object): return f(self, *args, **kwargs) return wrapper - def __init__(self, pool): + def __init__(self, pool, serialized=False): self._pool = pool + self._serialized = serialized self._cnx = pool.getconn() self._obj = self._cnx.cursor(cursor_factory=psycopg1cursor) self.autocommit(False) @@ -168,7 +169,8 @@ class Cursor(object): @check def autocommit(self, on): - self._cnx.set_isolation_level([ISOLATION_LEVEL_SERIALIZABLE, ISOLATION_LEVEL_AUTOCOMMIT][bool(on)]) + offlevel = [ISOLATION_LEVEL_READ_COMMITTED, ISOLATION_LEVEL_SERIALIZABLE][bool(self._serialized)] + self._cnx.set_isolation_level([offlevel, ISOLATION_LEVEL_AUTOCOMMIT][bool(on)]) @check def commit(self): @@ -190,6 +192,9 @@ class ConnectionPool(object): def cursor(self): return Cursor(self) + def serialized_cursor(self): + return Cursor(self, True) + def __getattr__(self, name): return getattr(self._pool, name) From 5d4c72c177e720487fe7dff501dafd0b46bb38be Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Sat, 31 Jan 2009 21:29:14 +0100 Subject: [PATCH 06/12] [FIX] Avoid an infinite loop when a module can not be physically found. Thanks a lot to P. Christeas for the initial patch. bzr revid: christophe@taupe-20090131202914-m3stut6b62ysd0dm --- bin/addons/__init__.py | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 8d630b267b1..fcc60ca1809 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -275,12 +275,14 @@ def get_modules(): def create_graph(module_list, force=None): graph = Graph() - return upgrade_graph(graph, module_list, force) + upgrade_graph(graph, module_list, force) + return graph def upgrade_graph(graph, module_list, force=None): if force is None: force = [] packages = [] + len_graph = len(graph) for module in module_list: try: mod_path = get_module_path(module) @@ -326,8 +328,11 @@ def upgrade_graph(graph, module_list, force=None): for package in later: unmet_deps = filter(lambda p: p not in graph, dependencies[package]) logger.notifyChannel('init', netsvc.LOG_ERROR, 'module %s: Unmet dependencies: %s' % (package, ', '.join(unmet_deps))) - - return graph + + result = len(graph) - len_graph + if result != len(module_list): + logger.notifyChannel('init', netsvc.LOG_WARNING, 'Not all modules have loaded.') + return result def init_module_objects(cr, module_name, obj_list): @@ -682,14 +687,23 @@ def load_modules(db, force_demo=False, status=None, update_module=False): STATES_TO_LOAD += ['to install'] + loop_guardrail = 0 while True: + loop_guardrail += 1 + if loop_guardrail > 100: + raise ProgrammingError() cr.execute("SELECT name from ir_module_module WHERE state in (%s)" % ','.join(['%s']*len(STATES_TO_LOAD)), STATES_TO_LOAD) module_list = [name for (name,) in cr.fetchall() if name not in graph] if not module_list: break - - upgrade_graph(graph, module_list, force) + + new_modules_in_graph = upgrade_graph(graph, module_list, force) + if new_modules_in_graph == 0: + # nothing to load + break + + logger.notifyChannel('init', netsvc.LOG_DEBUG, 'Updating graph with %d more modules' % (len(module_list))) r = load_module_graph(cr, graph, status, report=report) has_updates = has_updates or r @@ -703,7 +717,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False): obj = pool.get(model) if obj: obj._check_removed_columns(cr, log=True) - + if report.get_report(): logger.notifyChannel('init', netsvc.LOG_INFO, report) From f04edba892820b07b11973f2407d09d731dbdabc Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 2 Feb 2009 08:13:47 +0100 Subject: [PATCH 07/12] [FIX] allow to use the rowspan attribute on the group tag lp bug: https://launchpad.net/bugs/323551 fixed bzr revid: stephane@tinyerp.com-20090202071347-af02011b97ro5237 --- bin/addons/base/rng/view.rng | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/addons/base/rng/view.rng b/bin/addons/base/rng/view.rng index 6255c9f7650..40db5265c92 100644 --- a/bin/addons/base/rng/view.rng +++ b/bin/addons/base/rng/view.rng @@ -272,6 +272,7 @@ + From 720ff8a9e56117f027c064293a0ed1df4b6fc47b Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 2 Feb 2009 14:02:14 +0100 Subject: [PATCH 08/12] [FIX] Use the translation in the selection field for the print screen functionnality lp bug: https://launchpad.net/bugs/323229 fixed bzr revid: stephane@tinyerp.com-20090202130214-z3bknh0n2j0wpspa --- bin/report/printscreen/ps_list.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bin/report/printscreen/ps_list.py b/bin/report/printscreen/ps_list.py index b59be30f1c8..d75d2ecad20 100644 --- a/bin/report/printscreen/ps_list.py +++ b/bin/report/printscreen/ps_list.py @@ -156,8 +156,15 @@ class report_printscreen_list(report_int): if fields[f]['type']=='many2one' and line[f]: line[f]= line[f][1] + if fields[f]['type']=='selection' and line[f]: + for key, value in fields[f]['selection']: + if key == line[f]: + line[f] = value + break + if fields[f]['type'] in ('one2many','many2many') and line[f]: line[f] = '( '+tools.ustr(len(line[f])) + ' )' + if fields[f]['type'] == 'float': precision=(('digits' in fields[f]) and fields[f]['digits'][1]) or 2 line[f]='%.2f'%(line[f]) From 557cc93aae95e85cd2d9cb662127b3aec0c86a3b Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 2 Feb 2009 15:07:15 +0100 Subject: [PATCH 09/12] [IMP] Add a new function, last_day_of_current_month, this function returns the last day of the current month. bzr revid: stephane@tinyerp.com-20090202140715-e5lw28lvrd9fep13 --- bin/osv/orm.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bin/osv/orm.py b/bin/osv/orm.py index 737fc40c194..ff48da700a0 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -40,6 +40,7 @@ # import time +import calendar import types import string import netsvc @@ -62,6 +63,12 @@ from tools.config import config regex_order = re.compile('^([a-zA-Z0-9_]+( desc)?( asc)?,?)+$', re.I) +def last_day_of_current_month(): + import datetime + import calendar + today = datetime.date.today() + last_day = str(calendar.monthrange(today.year, today.month)[1]) + return time.strftime('%Y-%m-' + last_day) def intersect(la, lb): return filter(lambda x: x in lb, la) From 392bf7f4427f921544144dc94b59ebcc2bbd0f0f Mon Sep 17 00:00:00 2001 From: Stephane Wirtel Date: Mon, 2 Feb 2009 15:35:18 +0100 Subject: [PATCH 10/12] [FIX] Python typo fix lp bug: https://launchpad.net/bugs/324285 fixed bzr revid: stephane@tinyerp.com-20090202143518-6x96x6syd82se26d --- bin/service/web_services.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/service/web_services.py b/bin/service/web_services.py index d4b2a6e9780..10a11a4819f 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -204,7 +204,7 @@ class db(netsvc.Service): cr = db.serialized_cursor() cr.autocommit(True) # XXX inhibit the effect of a serialized cursor. is it what we want ? try: - cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE 'template0'""" % db_name) + cr.execute("""CREATE DATABASE "%s" ENCODING 'unicode' TEMPLATE "template0" """ % db_name) finally: cr.close() sql_db.close_db('template1') From de2e10095ebf057b91dc02713c34180aa96caacf Mon Sep 17 00:00:00 2001 From: husen daudi Date: Tue, 3 Feb 2009 13:01:23 +0530 Subject: [PATCH 11/12] bugfix lp bug: https://launchpad.net/bugs/323638 fixed bzr revid: hda@hda-20090203073123-2c0zibxh495o7ldo --- bin/addons/base/res/partner/partner.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/addons/base/res/partner/partner.py b/bin/addons/base/res/partner/partner.py index f9e6d74c515..cfe1cb41710 100644 --- a/bin/addons/base/res/partner/partner.py +++ b/bin/addons/base/res/partner/partner.py @@ -32,12 +32,12 @@ class res_partner_function(osv.osv): _description = 'Function of the contact' _columns = { 'name': fields.char('Function Name', size=64, required=True), - 'code': fields.char('Code', size=8), - 'ref':fields.char('Notes', size=32, required=True), + 'code': fields.char('Code', size=8, required=True), + 'ref':fields.char('Notes', size=32,), } _order = 'name' _sql_constraints = [ - ('ref_uniq', 'unique (ref)', 'The Notes of the Partner Function must be unique !') + ('code_uniq', 'unique (code)', 'The Code of the Partner Function must be unique !') ] res_partner_function() From 7f28b06e6a7ad5124f69b4a3159e54a878b95a35 Mon Sep 17 00:00:00 2001 From: "mra (Open ERP)" Date: Tue, 3 Feb 2009 15:17:03 +0530 Subject: [PATCH 12/12] bug fix on res.partner.function demo data bzr revid: mra@tinyerp.com-20090203094703-b0qt00qjudqa7t5h --- bin/addons/base/res/partner/partner_data.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/bin/addons/base/res/partner/partner_data.xml b/bin/addons/base/res/partner/partner_data.xml index 1e66a8f2183..61286b755d3 100644 --- a/bin/addons/base/res/partner/partner_data.xml +++ b/bin/addons/base/res/partner/partner_data.xml @@ -10,13 +10,13 @@ Corp. Corp. - + partner Ltd ltd - + contact Madam @@ -32,18 +32,18 @@ Sir M. - + Director - CEO + CEO Chief Technical Officer - CTO + CTO Salesman - SAL + SAL