From 2081fa095961bfa5685b38e17024a77070aceae9 Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Sat, 28 Nov 2009 00:11:26 +0100 Subject: [PATCH 01/10] [FIX] connection pool when database password is provided (thanks to Syleam Crew) lp bug: https://launchpad.net/bugs/488234 fixed bzr revid: chs@tinyerp.com-20091127231126-lbdmz9i9tm50k8f7 --- bin/sql_db.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/bin/sql_db.py b/bin/sql_db.py index 5c288efd817..b36634c5956 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -235,7 +235,7 @@ class ConnectionPool(object): result = None for i, (cnx, used) in enumerate(self._connections): - if not used and cnx.dsn == dsn: + if not used and dsn_are_equals(cnx.dsn, dsn): self._debug('Existing connection found at index %d' % i) self._connections.pop(i) @@ -276,7 +276,7 @@ class ConnectionPool(object): @locked def close_all(self, dsn): for i, (cnx, used) in tools.reverse_enumerate(self._connections): - if cnx.dsn == dsn: + if dsn_are_equals(cnx.dsn, dsn): cnx.close() self._connections.pop(i) @@ -295,6 +295,7 @@ class Connection(object): def __del__(self): if self._unique: + close_db(self.dbname) self.__LOCKS[self.dbname].release() def cursor(self, serialized=False): @@ -313,6 +314,13 @@ for p in ('host', 'port', 'user', 'password'): def dsn(db_name): return '%sdbname=%s' % (_dsn, db_name) +def dsn_are_equals(first, second): + def key(dsn): + k = dict(x.split('=', 1) for x in dsn.strip().split()) + k.pop('password', None) # password is not relevant + return k + return key(first) == key(second) + _Pool = ConnectionPool(int(tools.config['db_maxconn'])) From f51520986054b7cc0eb84958c46840901b49d9ef Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Sat, 28 Nov 2009 00:47:26 +0100 Subject: [PATCH 02/10] [IMP] sql_log bzr revid: chs@tinyerp.com-20091127234726-1k4g37h036x0hy7a --- bin/sql_db.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/bin/sql_db.py b/bin/sql_db.py index b36634c5956..6d2d8b779ef 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -53,6 +53,7 @@ psycopg2.extensions.register_type(psycopg2.extensions.new_type((700, 701, 1700,) import tools from tools.func import wraps from datetime import datetime as mdt +from datetime import timedelta import threading import re @@ -128,18 +129,21 @@ class Cursor(object): raise if self.sql_log: + delay = mdt.now() - now + delay = delay.seconds * 1E6 + delay.microseconds + log("query: %s" % self._obj.query) self.sql_log_count+=1 res_from = re_from.match(query.lower()) if res_from: self.sql_from_log.setdefault(res_from.group(1), [0, 0]) self.sql_from_log[res_from.group(1)][0] += 1 - self.sql_from_log[res_from.group(1)][1] += mdt.now() - now + self.sql_from_log[res_from.group(1)][1] += delay res_into = re_into.match(query.lower()) if res_into: self.sql_into_log.setdefault(res_into.group(1), [0, 0]) self.sql_into_log[res_into.group(1)][0] += 1 - self.sql_into_log[res_into.group(1)][1] += mdt.now() - now + self.sql_into_log[res_into.group(1)][1] += delay return res def print_log(self): @@ -155,9 +159,11 @@ class Cursor(object): sum = 0 log("SQL LOG %s:" % (type,)) for r in sqllogitems: - log("table: %s: %s/%s" %(r[0], str(r[1][1]), r[1][0])) + delay = timedelta(microseconds=r[1][1]) + log("table: %s: %s/%s" %(r[0], str(delay), r[1][0])) sum+= r[1][1] - log("SUM:%s/%d" % (sum, self.sql_log_count)) + sum = timedelta(microseconds=sum) + log("SUM:%s/%d" % (str(sum), self.sql_log_count)) sqllogs[type].clear() process('from') process('into') From bfa9ea99e377000edd1dfce38bdd2234f440bc3b Mon Sep 17 00:00:00 2001 From: "Jay (Open ERP)" Date: Mon, 30 Nov 2009 14:11:25 +0530 Subject: [PATCH 03/10] [FIX] Module informtion was not getting updated on upgrading module lp bug: https://launchpad.net/bugs/487723 fixed bzr revid: jvo@tinyerp.com-20091130084125-1kqrxbdti3a6jxga --- bin/addons/__init__.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/bin/addons/__init__.py b/bin/addons/__init__.py index 11503306743..0ac375fcde1 100644 --- a/bin/addons/__init__.py +++ b/bin/addons/__init__.py @@ -82,7 +82,7 @@ class Graph(dict): ## and we update the default values with values from the database additional_data.update(dict([(x.pop('name'), x) for x in cr.dictfetchall()])) - + for package in self.values(): for k, v in additional_data[package.name].items(): setattr(package, k, v) @@ -602,6 +602,16 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, **kwargs): if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): has_updates = True for kind in ('init', 'update'): + if package.state=='to upgrade': + # upgrading the module information + modobj.write(cr, 1, [mid], { + 'description': package.data.get('description', ''), + 'shortdesc': package.data.get('name', ''), + 'author': package.data.get('author', 'Unknown'), + 'website': package.data.get('website', ''), + 'license': package.data.get('license', 'GPL-2'), + 'certificate': package.data.get('certificate') or None, + }) for filename in package.data.get('%s_xml' % kind, []): logger.notifyChannel('init', netsvc.LOG_INFO, 'module %s: loading %s' % (m, filename)) name, ext = os.path.splitext(filename) From 21749941eef20aeaf0173619ea7bf48c6957feb4 Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Mon, 30 Nov 2009 17:01:31 +0100 Subject: [PATCH 04/10] [FIX] fields: '_fnct_write' should pass context object to the 'write' method lp bug: https://launchpad.net/bugs/489355 fixed bzr revid: olt@tinyerp.com-20091130160131-bv9g7y9vf0gdpa53 --- bin/osv/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index dc5e2a9fd4a..92c9c634365 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -721,7 +721,7 @@ class related(function): t_id=t_data['id'] t_data = t_data[self.arg[i]] if t_id: - obj.pool.get(field_detail['object']).write(cr,uid,[t_id],{args[-1]:values}) + obj.pool.get(field_detail['object']).write(cr,uid,[t_id],{args[-1]:values}, context=context) def _fnct_read(self, obj, cr, uid, ids, field_name, args, context=None): self._field_get2(cr, uid, obj, context) From 0858a7c066fd793cd33c116752d825cc3f59b840 Mon Sep 17 00:00:00 2001 From: "Harry (Open ERP)" Date: Tue, 1 Dec 2009 12:05:57 +0530 Subject: [PATCH 05/10] [FIX] quality_integration_server : fixed bug on make link bzr revid: hmo@tinyerp.com-20091201063557-j0k6ocjkt2djbq84 --- .../base_quality_interrogation.py | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/bin/addons/quality_integration_server/base_quality_interrogation.py b/bin/addons/quality_integration_server/base_quality_interrogation.py index eb141b09453..6350789a9e9 100755 --- a/bin/addons/quality_integration_server/base_quality_interrogation.py +++ b/bin/addons/quality_integration_server/base_quality_interrogation.py @@ -209,23 +209,20 @@ def drop_db(uri, dbname): def make_links(uri, uid, dbname, source, destination, module, user, pwd): if module in ('base','quality_integration_server'): return True - for path in source: - if os.path.isdir(path + '/' + module): - if not os.path.islink(destination + '/' + module): - os.symlink(path + '/' + module, destination + '/' + module) - obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object') - execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'update_list') - module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','=',module)]) - if len(module_ids): - data = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'read', module_ids[0],['name','dependencies_id']) - dep_datas = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module.dependency', 'read', data['dependencies_id'],['name']) - for dep_data in dep_datas: - make_links(uri, uid, dbname, source, destination, dep_data['name'], user, pwd) - break - else: - if os.path.islink(destination + '/' + module): - os.unlink(destination + '/' + module) - break + if not os.path.islink(destination + '/' + module): + if not os.path.isdir(destination + '/' + module): + for path in source: + if os.path.isdir(path + '/' + module): + os.symlink(path + '/' + module, destination + '/' + module) + obj_conn = xmlrpclib.ServerProxy(uri + '/xmlrpc/object') + execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'update_list') + module_ids = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'search', [('name','=',module)]) + if len(module_ids): + data = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module', 'read', module_ids[0],['name','dependencies_id']) + dep_datas = execute(obj_conn, 'execute', dbname, uid, pwd, 'ir.module.module.dependency', 'read', data['dependencies_id'],['name']) + for dep_data in dep_datas: + make_links(uri, uid, dbname, source, destination, dep_data['name'], user, pwd) + return True return False def install_module(uri, dbname, modules, addons='', extra_addons='', user='admin', pwd='admin'): From bb6e26450e975a218434f46ede4b98cb0c701fc8 Mon Sep 17 00:00:00 2001 From: "R.Messier" <> Date: Tue, 1 Dec 2009 16:31:49 +0530 Subject: [PATCH 06/10] [FIX] RAW reports creation corrected lp bug: https://launchpad.net/bugs/490604 fixed bzr revid: jvo@tinyerp.com-20091201110149-2flhfi59r9t909n4 --- bin/report/interface.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/report/interface.py b/bin/report/interface.py index 09ea80720ac..cd548301c26 100644 --- a/bin/report/interface.py +++ b/bin/report/interface.py @@ -88,14 +88,14 @@ class report_rml(report_int): def create(self, cr, uid, ids, datas, context): xml = self.create_xml(cr, uid, ids, datas, context) xml = tools.ustr(xml).encode('utf8') - if datas.get('report_type', 'pdf') == 'raw': - return xml + report_type = datas.get('report_type', 'pdf') + if report_type == 'raw': + return (xml,report_type) rml = self.create_rml(cr, xml, uid, context) pool = pooler.get_pool(cr.dbname) ir_actions_report_xml_obj = pool.get('ir.actions.report.xml') report_xml_ids = ir_actions_report_xml_obj.search(cr, uid, [('report_name', '=', self.name[7:])], context=context) self.title = report_xml_ids and ir_actions_report_xml_obj.browse(cr,uid,report_xml_ids)[0].name or 'OpenERP Report' - report_type = datas.get('report_type', 'pdf') create_doc = self.generators[report_type] pdf = create_doc(rml, title=self.title) return (pdf, report_type) From 229c73d741a2d902ae64335ec5bdeeb58d8fa54e Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 1 Dec 2009 14:19:08 +0100 Subject: [PATCH 07/10] [FIX] allow related fields to point to one2many and many2many fields lp bug: https://launchpad.net/bugs/356628 fixed bzr revid: chs@tinyerp.com-20091201131908-k5l5tmtpjq3m975x --- bin/osv/fields.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/bin/osv/fields.py b/bin/osv/fields.py index 92c9c634365..e1d70978181 100644 --- a/bin/osv/fields.py +++ b/bin/osv/fields.py @@ -744,7 +744,7 @@ class related(function): except: t_data = False break - if field_detail['type'] in ('one2many', 'many2many'): + if field_detail['type'] in ('one2many', 'many2many') and i != len(self.arg) - 1: t_data = t_data[self.arg[i]][0] else: t_data = t_data[self.arg[i]] @@ -760,6 +760,12 @@ class related(function): for r in res: if res[r]: res[r] = (res[r], ng[res[r]]) + elif self._type in ('one2many', 'many2many'): + for r in res: + if res[r]: + res[r] = [x.id for x in res[r]] + + return res def __init__(self, *arg, **args): From e345e91365f2ab3c9130a3903715b1e1db5a477d Mon Sep 17 00:00:00 2001 From: Christophe Simonis Date: Tue, 1 Dec 2009 14:32:14 +0100 Subject: [PATCH 08/10] [FIX] db_exist method works as expected bzr revid: chs@tinyerp.com-20091201133214-8c6i1ohk5t5u79dz --- bin/service/web_services.py | 7 ++----- bin/sql_db.py | 9 +++++++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bin/service/web_services.py b/bin/service/web_services.py index a3280719f2c..ebd7f063d39 100644 --- a/bin/service/web_services.py +++ b/bin/service/web_services.py @@ -286,11 +286,8 @@ class db(netsvc.Service): return True def db_exist(self, db_name): - try: - db = sql_db.db_connect(db_name) - return True - except: - return False + ## Not True: in fact, check if connection to database is possible. The database may exists + return bool(sql_db.db_connect(db_name)) def list(self): db = sql_db.db_connect('template1') diff --git a/bin/sql_db.py b/bin/sql_db.py index 6d2d8b779ef..59d7bcaac1f 100644 --- a/bin/sql_db.py +++ b/bin/sql_db.py @@ -310,6 +310,15 @@ class Connection(object): def serialized_cursor(self): return self.cursor(True) + def __nonzero__(self): + """Check if connection is possible""" + try: + cr = self.cursor() + cr.close() + return True + except: + return False + _dsn = '' for p in ('host', 'port', 'user', 'password'): From 2f6de41fbfc211c2938f70110898d461bb1df54d Mon Sep 17 00:00:00 2001 From: "olt@tinyerp.com" <> Date: Wed, 2 Dec 2009 09:09:50 +0100 Subject: [PATCH 09/10] [FIX] base: wrong fr_FR translation for 'Delete Permission' bzr revid: olt@tinyerp.com-20091202080950-p3e68ch77ofgw74n --- bin/addons/base/i18n/fr_FR.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/addons/base/i18n/fr_FR.po b/bin/addons/base/i18n/fr_FR.po index 37de9712074..6c489f2901d 100644 --- a/bin/addons/base/i18n/fr_FR.po +++ b/bin/addons/base/i18n/fr_FR.po @@ -5247,7 +5247,7 @@ msgstr "Compter" #. module: base #: field:ir.model.access,perm_create:0 msgid "Create Access" -msgstr "Accès en Création" +msgstr "Accès en création" #. module: base #: code:addons/addons/use_control/module.py:0 @@ -10394,7 +10394,7 @@ msgstr ">" #. module: base #: field:ir.model.access,perm_unlink:0 msgid "Delete Permission" -msgstr "Supprimer une permission" +msgstr "Accès en suppression" #. module: base #: code:addons/addons/account_budget/wizard/wizard_budget_report.py:0 @@ -11369,4 +11369,4 @@ msgstr "Erreur de contrainte" #. module: base #: selection:ir.translation,type:0 msgid "SQL Constraint" -msgstr "SQL Contrainte" \ No newline at end of file +msgstr "SQL Contrainte" From 9bb02a1bb021b98aa4b3530e43f89721a6a02bb4 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 2 Dec 2009 11:06:58 +0100 Subject: [PATCH 10/10] [fix] use env for python shebang rather than hardcoding /usr/bin/python bzr revid: xmo@tinyerp.com-20091202100658-d2q66mu6kihgj8h5 --- bin/addons/module_graph.py | 2 +- bin/netsvc.py | 2 +- bin/openerp-server.py | 2 +- bin/osv/orm.py | 2 +- bin/report/render/odt2odt/__init__.py | 2 +- bin/report/render/rml2html/rml2html.py | 2 +- bin/tools/graph.py | 2 +- doc/tests/check_profile_l10n_all.py | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/bin/addons/module_graph.py b/bin/addons/module_graph.py index 68cfb679804..6a21e053ccf 100755 --- a/bin/addons/module_graph.py +++ b/bin/addons/module_graph.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # -*- encoding: utf-8 -*- ############################################################################## # diff --git a/bin/netsvc.py b/bin/netsvc.py index 56d0eb2918a..66c4d9e3dea 100644 --- a/bin/netsvc.py +++ b/bin/netsvc.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # -*- encoding: utf-8 -*- ############################################################################## # diff --git a/bin/openerp-server.py b/bin/openerp-server.py index 3971f2fa779..d6f1bf260bc 100755 --- a/bin/openerp-server.py +++ b/bin/openerp-server.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # -*- encoding: utf-8 -*- ############################################################################## # diff --git a/bin/osv/orm.py b/bin/osv/orm.py index c8469c1ccc5..df843225ad7 100644 --- a/bin/osv/orm.py +++ b/bin/osv/orm.py @@ -3074,4 +3074,4 @@ class orm(orm_template): return False return True -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/bin/report/render/odt2odt/__init__.py b/bin/report/render/odt2odt/__init__.py index 9163b6eb222..b033149a972 100644 --- a/bin/report/render/odt2odt/__init__.py +++ b/bin/report/render/odt2odt/__init__.py @@ -19,4 +19,4 @@ # along with this program. If not, see . # ############################################################################## -from odt2odt import parseNode \ No newline at end of file +from odt2odt import parseNode diff --git a/bin/report/render/rml2html/rml2html.py b/bin/report/render/rml2html/rml2html.py index 5e7bb5cf4e9..8f0197b32df 100644 --- a/bin/report/render/rml2html/rml2html.py +++ b/bin/report/render/rml2html/rml2html.py @@ -458,4 +458,4 @@ if __name__=="__main__": print 'Usage: trml2pdf input.rml >output.pdf' print 'Try \'trml2pdf --help\' for more information.' -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/bin/tools/graph.py b/bin/tools/graph.py index 9d246e4037f..d6a26deb3c2 100644 --- a/bin/tools/graph.py +++ b/bin/tools/graph.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # -*- encoding: utf-8 -*- ############################################################################## # diff --git a/doc/tests/check_profile_l10n_all.py b/doc/tests/check_profile_l10n_all.py index f85ebfeb946..610c2b494cf 100644 --- a/doc/tests/check_profile_l10n_all.py +++ b/doc/tests/check_profile_l10n_all.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # -*- encoding: utf-8 -*- ############################################################################## #