From b8551a5fcca83d88f798e480290fa7b1c9f17280 Mon Sep 17 00:00:00 2001 From: nvi-openerp Date: Wed, 17 Nov 2010 18:17:54 +0100 Subject: [PATCH 01/25] [IMP] wip bzr revid: nicolas.vanhoren@openerp.com-20101117171754-ay58hnzhsq56iq3s --- bin/addons/base/ir/__init__.py | 1 + bin/addons/base/maintenance/__init__.py | 1 + bin/addons/base/maintenance/maintenance.py | 120 +++++------------- .../base/maintenance/maintenance_view.xml | 8 -- bin/addons/base/security/ir.model.access.csv | 2 +- bin/tools/config.py | 23 ++-- bin/tools/maintenance.py | 89 ++++++++----- 7 files changed, 107 insertions(+), 137 deletions(-) diff --git a/bin/addons/base/ir/__init__.py b/bin/addons/base/ir/__init__.py index 343b50a6998..2f322d1aee1 100644 --- a/bin/addons/base/ir/__init__.py +++ b/bin/addons/base/ir/__init__.py @@ -34,6 +34,7 @@ import ir_exports import workflow import ir_rule import wizard +import ir_config_parameter # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/bin/addons/base/maintenance/__init__.py b/bin/addons/base/maintenance/__init__.py index 329c61301d9..a6adfa1302a 100644 --- a/bin/addons/base/maintenance/__init__.py +++ b/bin/addons/base/maintenance/__init__.py @@ -20,6 +20,7 @@ ############################################################################## import maintenance +import dbuuid # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py index 389d915512f..f4f97a2c5f5 100644 --- a/bin/addons/base/maintenance/maintenance.py +++ b/bin/addons/base/maintenance/maintenance.py @@ -20,60 +20,30 @@ ############################################################################## from osv import osv, fields -import pooler import time import netsvc -from tools.misc import debug from tools.misc import ustr from tools.translate import _ import tools.maintenance as tm -class maintenance_contract_module(osv.osv): - _name ="maintenance.contract.module" - _description = "maintenance contract modules" - _columns = { - 'name' : fields.char('Name', size=128, required=True), - 'version': fields.char('Version', size=64,), - } - -maintenance_contract_module() - class maintenance_contract(osv.osv): _name = "maintenance.contract" _description = "Maintenance Contract" def _get_valid_contracts(self, cr, uid): return [contract for contract in self.browse(cr, uid, self.search(cr, uid, [])) if contract.state == 'valid'] - + def status(self, cr, uid): - covered_modules, uncovered_modules = set(), set() - - status = 'none' - for contract in self._get_valid_contracts(cr, uid): - covered_modules.update([m.name for m in contract.module_ids]) - - if covered_modules: - modobj = self.pool.get('ir.module.module') - modids = modobj.search(cr, uid, [('state', '=', 'installed')]) - uncovered_modules = set(m.name for m in modobj.browse(cr, uid, modids)) - covered_modules - status = ['full', 'partial'][len(uncovered_modules) > 0] - + contracts = self._get_valid_contracts(cr, uid) return { - 'status': status, - 'uncovered_modules': list(uncovered_modules), + 'status': "full" if contracts else "none" , + 'uncovered_modules': list(), } def send(self, cr, uid, tb, explanations, remarks=None): - status = self.status(cr, uid) - if status['status'] != 'full': - raise osv.except_osv(_('Error'), _("Your can't submit bug reports due to uncovered modules: %s") % (', '.join(status['uncovered_modules']),)) - - dbmsg = _('This error occurs on database %s') % (cr.dbname,) if not remarks: - remarks = dbmsg - else: - remarks += '\n\n-----\n' + dbmsg + remarks = "" valid_contracts = self._get_valid_contracts(cr, uid) @@ -81,8 +51,10 @@ class maintenance_contract(osv.osv): rc = None try: for contract in valid_contracts: - rc = tm.remote_contract(contract.name, contract.password) + rc = tm.remote_contract(cr, uid, contract.name) + if rc.id: + contract_name = contract.name break rc = None @@ -90,34 +62,25 @@ class maintenance_contract(osv.osv): raise osv.except_osv(_('Error'), _('Unable to find a valid contract')) origin = 'client' - crm_case_id = rc.submit(rc.id, tb, explanations, remarks or '', origin) + dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') + crm_case_id = rc.submit({ + 'contract_name': contract_name, + 'tb': tb, + 'explanations': explanations, + 'remarks': remarks, + 'origin': origin, + 'dbname': cr.dbname, + 'dbuuid': dbuuid}) except tm.RemoteContractException, rce: netsvc.Logger().notifyChannel('maintenance', netsvc.LOG_INFO, rce) except osv.except_osv: raise except: - pass + pass # don't want to throw exceptions in exception handler - cid = rc and rc.name or valid_contracts[0].name - try: - # as backup, put it also in another database... - import urllib - args = urllib.urlencode({ - 'contract_id': cid, - 'crm_case_id': crm_case_id or 0, - 'explanation': explanations, - 'remark': remarks or '', - 'tb': tb, - }) - uo = urllib.urlopen('http://www.openerp.com/scripts/maintenance.php', args) - submit_result = uo.read() - debug(submit_result) - uo.close() - except: - if not crm_case_id: - # TODO schedule a retry (ir.cron) - return False + if not crm_case_id: + return False return True def _valid_get(self, cr, uid, ids, field_name, arg, context=None): @@ -127,16 +90,11 @@ class maintenance_contract(osv.osv): return res _columns = { - 'name' : fields.char('Contract ID', size=256, required=True, readonly=True), - 'password' : fields.char('Password', size=64, invisible=True, required=True, readonly=True), + 'name' : fields.char('Contract ID', size=384, required=True, readonly=True), 'date_start' : fields.date('Starting Date', readonly=True), 'date_stop' : fields.date('Ending Date', readonly=True), - 'module_ids' : fields.many2many('maintenance.contract.module', 'maintenance_contract_module_rel', 'contract_id', 'module_id', 'Covered Modules', readonly=True), 'state' : fields.function(_valid_get, method=True, string="State", type="selection", selection=[('valid', 'Valid'),('unvalid', 'Unvalid')], readonly=True), - 'kind' : fields.selection([('full', 'Full'),('partial', 'Partial')], 'Kind', required=True, readonly=True), - } - _defaults = { - 'password' : lambda obj,cr,uid,context={} : '', + 'kind' : fields.char('Kind', size=64, required=True, readonly=True), } _sql_constraints = [ ('uniq_name', 'unique(name)', "Your maintenance contract is already subscribed in the system !") @@ -149,8 +107,7 @@ class maintenance_contract_wizard(osv.osv_memory): _name = 'maintenance.contract.wizard' _columns = { - 'name' : fields.char('Contract ID', size=256, required=True ), - 'password' : fields.char('Password', size=64, required=True), + 'name' : fields.char('Contract ID', size=384, required=True ), 'state' : fields.selection([('draft', 'Draft'),('validated', 'Validated'),('unvalidated', 'Unvalidated')], 'States'), } @@ -159,46 +116,31 @@ class maintenance_contract_wizard(osv.osv_memory): } def action_validate(self, cr, uid, ids, context=None): + raise Exception("hahaha, this is a dirty exception to make you fail") if not ids: return False - - module_proxy = self.pool.get('ir.module.module') - module_ids = module_proxy.search(cr, uid, [('state', '=', 'installed')]) - modules = module_proxy.read(cr, uid, module_ids, ['name', 'installed_version']) - - contract = self.read(cr, uid, ids, ['name', 'password'])[0] + contract = self.read(cr, uid, ids, ['name'])[0] try: - contract_info = tm.remote_contract(contract['name'], contract['password'], modules) + contract_info = tm.remote_contract(cr, uid, contract['name']) except tm.RemoteContractException, rce: raise osv.except_osv(_('Error'), ustr(rce)) - is_ok = contract_info['status'] in ('partial', 'full') - if is_ok: - module_ids = [] - if contract_info['modules_with_contract']: - for name, version in contract_info['modules_with_contract']: - contract_module = self.pool.get('maintenance.contract.module') - res = contract_module.search(cr, uid, [('name', '=', name),('version', '=', version)]) - if not res: - id = contract_module.create(cr, uid, { 'name' : name, 'version' : version } ) - else: - id = res[0] - module_ids.append(id) + if contract_info['status'] == "valid": self.pool.get('maintenance.contract').create( cr, uid, { 'name' : contract['name'], - 'password' : contract['password'], 'date_start' : contract_info['date_from'], 'date_stop' : contract_info['date_to'], - 'kind' : contract_info['status'], - 'module_ids' : [(6,0,module_ids)], + 'kind' : contract_info['kind'], } ) - return self.write(cr, uid, ids, {'state' : ('unvalidated', 'validated')[is_ok] }, context=context) + return self.write(cr, uid, ids, + {'state' : ['validated' if contract_info['status'] == "valid" else 'unvalidated'] }, + context=context) maintenance_contract_wizard() diff --git a/bin/addons/base/maintenance/maintenance_view.xml b/bin/addons/base/maintenance/maintenance_view.xml index 836344a52df..fac95d705a3 100644 --- a/bin/addons/base/maintenance/maintenance_view.xml +++ b/bin/addons/base/maintenance/maintenance_view.xml @@ -27,13 +27,6 @@ - - - - - - - @@ -94,7 +87,6 @@ - diff --git a/bin/addons/base/security/ir.model.access.csv b/bin/addons/base/security/ir.model.access.csv index 62eb8ffe2b1..fea55ecc0bd 100644 --- a/bin/addons/base/security/ir.model.access.csv +++ b/bin/addons/base/security/ir.model.access.csv @@ -113,7 +113,6 @@ "access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1 "access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0 "access_maintenance_group_user","maintenance_contract group_user","model_maintenance_contract","group_system",1,1,1,1 -"access_maintenance_contract_module","maintenance.contract.module","model_maintenance_contract_module","group_system",1,1,1,1 "access_multi_company_default user","multi_company_default all","model_multi_company_default",,1,0,0,0 "access_multi_company_default manager","multi_company_default Manager","model_multi_company_default","group_erp_manager",1,1,1,1 "access_ir_filter all","ir_filters all","model_ir_filters",,1,0,0,0 @@ -123,3 +122,4 @@ "access_res_widget","res.widget","model_res_widget","group_erp_manager",1,1,1,1 "access_res_widget_user","res.widget.user","model_res_widget",,1,0,0,0 "access_res_log_all","res.log","model_res_log",,1,1,1,1 +"access_ir_config_parameter","ir_config_parameter","model_ir_config_parameter",,1,0,0,0 diff --git a/bin/tools/config.py b/bin/tools/config.py index 2964870d427..3e776d83135 100644 --- a/bin/tools/config.py +++ b/bin/tools/config.py @@ -31,8 +31,8 @@ def check_ssl(): try: from OpenSSL import SSL import socket - - return hasattr(socket, 'ssl') + + return hasattr(socket, 'ssl') and hasattr(SSL, "Connection") except: return False @@ -91,6 +91,10 @@ class configmanager(object): 'static_http_url_prefix': None, 'secure_cert_file': 'server.cert', 'secure_pkey_file': 'server.pkey', + 'maintenance_server': 'http://tiny.my.odoo.com:8069/xmlrpc/', + 'maintenance_db': 'tiny_belgium', + 'maintenance_login': 'maintenance', + 'maintenance_password': 'maintenance', } self.misc = {} @@ -224,7 +228,7 @@ class configmanager(object): parser.add_option_group(security) def parse_config(self): - (opt, args) = self.parser.parse_args() + opt = self.parser.parse_args()[0] def die(cond, msg): if cond: @@ -317,7 +321,7 @@ class configmanager(object): # If an explicit TZ was provided in the config, make sure it is known try: import pytz - tz = pytz.timezone(self.options['timezone']) + pytz.timezone(self.options['timezone']) except pytz.UnknownTimeZoneError: die(True, "The specified timezone (%s) is invalid" % self.options['timezone']) except: @@ -374,7 +378,10 @@ class configmanager(object): fp.close() if is_win32: - import _winreg + try: + import _winreg + except ImportError: + _winreg = None x=_winreg.ConnectRegistry(None,_winreg.HKEY_LOCAL_MACHINE) y = _winreg.OpenKey(x, r"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", 0,_winreg.KEY_ALL_ACCESS) _winreg.SetValueEx(y,"PGPASSFILE", 0, _winreg.REG_EXPAND_SZ, filename ) @@ -436,7 +443,7 @@ class configmanager(object): p = ConfigParser.ConfigParser() loglevelnames = dict(zip(self._LOGLEVELS.values(), self._LOGLEVELS.keys())) p.add_section('options') - for opt in self.options.keys(): + for opt in sorted(self.options.keys()): if opt in ('version', 'language', 'translate_out', 'translate_in', 'init', 'update'): continue if opt in ('log_level', 'assert_exit_level'): @@ -444,8 +451,8 @@ class configmanager(object): else: p.set('options', opt, self.options[opt]) - for sec in self.misc.keys(): - for opt in self.misc[sec].keys(): + for sec in sorted(self.misc.keys()): + for opt in sorted(self.misc[sec].keys()): p.set(sec,opt,self.misc[sec][opt]) # try to create the directories and write the file diff --git a/bin/tools/maintenance.py b/bin/tools/maintenance.py index 83cf5e3b8bd..6789ac5f8f8 100644 --- a/bin/tools/maintenance.py +++ b/bin/tools/maintenance.py @@ -20,50 +20,77 @@ ############################################################################## import xmlrpclib +import config +import logging +import pooler -class RemoteContractException(Exception): pass +_logger = logging.getLogger(__name__) -class remote_contract(object): - def __init__(self, contract_id, contract_password, modules=None): - self.__server = 'http://tiny.my.odoo.com:8069/xmlrpc/' - self.__db = "tiny_belgium" - self.__password = "maintenance" - self.__login = "maintenance" +class RemoteConnectionException(Exception): + pass + +class RemoteConnection: + + def __init__(self, server, db, login, password): + self._server = server.strip() + if not self._server.endswith("/"): + self._server += "/" + self._db = db + self._login = login + self._password = password - rpc = xmlrpclib.ServerProxy(self.__server + 'common') + rpc = xmlrpclib.ServerProxy(self._server + "xmlrpc/common") try: - self.__userid = rpc.login(self.__db, self.__login, self.__password) + self._userid = rpc.login(self._db, self._login, self._password) except: - raise RemoteContractException("Unable to contact the migration server") + raise RemoteConnectionException("Unable to contact the remote server") - if not self.__userid: - raise RemoteContractException("Unable to contact the migration server") - - self.__rpc = xmlrpclib.ServerProxy(self.__server + 'object') + if not self._userid: + raise RemoteConnectionException("Unable to contact the remote server") - - contract = { - 'name': contract_id, - 'password': contract_password, - } - if modules is None: - modules = [] - - info = self.check_contract(modules, contract) - for n in info: - setattr(self, n, info[n]) - - self.name = contract_id - self.contract_id = self.name - self.password = contract_password + self._rpc = xmlrpclib.ServerProxy(self._server + "xmlrpc/object") + def get_remote_object(self, object): + return RemoteObject(self, object) + +class RemoteObject(object): + + def __init__(self, connection, object): + self._c = connection + self._object = object + def __getattr__(self, fun): def remote_call(*args, **kwargs): - return self.__rpc.execute(self.__db, self.__userid, self.__password, 'maintenance.maintenance', fun, *args, **kwargs) + return self._c._rpc.execute(self._c._db, self._c._userid, + self._c._password, self._object, fun, *args, **kwargs) return remote_call - + def __getitem__(self, item): return getattr(self, item) + +class RemoteContractException(Exception): pass + +def remote_contract(cr, uid, contract_id): + pool = pooler.get_pool(cr.dbname) + dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') + + try: + ro = RemoteConnection(config.config.get("maintenance_server"), config.config.get("maintenance_db"), + config.config.get("maintenance_login"), config.config.get("maintenance_password") + ).get_remote_object('maintenance.maintenance') + except: + _logger.exception("Exception") + raise RemoteContractException("Unable to contact the migration server") + + info = ro.check_contract({ + "contract_name": contract_id, + "dbuuid": dbuuid, + "dbname": cr.dbname}) + for n in info: + setattr(ro, n, info[n]) + + return ro + # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: From d5debf686f752cbb417a3150eba48aaf10baaf1a Mon Sep 17 00:00:00 2001 From: nvi-openerp Date: Thu, 18 Nov 2010 10:34:12 +0100 Subject: [PATCH 02/25] [IMP] wip bzr revid: nicolas.vanhoren@openerp.com-20101118093412-czjcmcqupngfqjnt --- .bzrignore | 3 + bin/addons/base/ir/ir_config_parameter.py | 81 ++++++++++++++++++++++ bin/addons/base/maintenance/dbuuid.py | 45 ++++++++++++ bin/addons/base/maintenance/maintenance.py | 12 ++-- bin/tools/maintenance.py | 2 +- 5 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 bin/addons/base/ir/ir_config_parameter.py create mode 100644 bin/addons/base/maintenance/dbuuid.py diff --git a/.bzrignore b/.bzrignore index 5581ee20f94..f67a6e2c6b6 100644 --- a/.bzrignore +++ b/.bzrignore @@ -18,3 +18,6 @@ bin/python2.6 build/ bin/yolk bin/pil*.py +.project +.pydevproject +.settings diff --git a/bin/addons/base/ir/ir_config_parameter.py b/bin/addons/base/ir/ir_config_parameter.py new file mode 100644 index 00000000000..a7502490ea4 --- /dev/null +++ b/bin/addons/base/ir/ir_config_parameter.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## +""" +A module to store some configuration parameters relative to a whole database. +""" + +from osv import osv,fields + +class ir_config_parameter(osv.osv): + """ An osv to old configuration parameters for a given database. + + To be short, it's just a global dictionnary of strings stored in a table. """ + + _name = 'ir.config_parameter' + + _columns = { + # The key of the configuration parameter. + 'key': fields.char('Key', size=256, required=True, select=1), + # The value of the configuration parameter. + 'value': fields.text('Value', required=True), + } + + _sql_constraints = [ + ('key_uniq', 'unique (key)', 'Key must be unique.') + ] + + def get_param(self, cr, uid, key, context=None): + """ Get the value of a parameter. + + @param key: The key of the parameter. + @type key: string + @return: The value of the parameter, False if it does not exist. + @rtype: string + """ + ids = self.search(cr, uid, [('key','=',key)], context=context) + if not ids: + return False + param = self.browse(cr, uid, ids[0], context=context) + value = param.value + return value + + def set_param(self, cr, uid, key, value, context=None): + """ Set the value of a parameter. + + @param key: The key of the parameter. + @type key: string + @param value: The value of the parameter. + @type value: string + @return: Return the previous value of the parameter of False if it did + not existed. + @rtype: string + """ + ids = self.search(cr, uid, [('key','=',key)], context=context) + if ids: + param = self.browse(cr, uid, ids[0], context=context) + old = param.value + self.write(cr, uid, ids, {'value': value}, context=context) + return old + else: + self.create(cr, uid, {'key': key, 'value': value}, context=context) + return False + +ir_config_parameter() diff --git a/bin/addons/base/maintenance/dbuuid.py b/bin/addons/base/maintenance/dbuuid.py new file mode 100644 index 00000000000..1cbb10fab1b --- /dev/null +++ b/bin/addons/base/maintenance/dbuuid.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## +""" +A module to handle a database UUID. That uuid will be stored in the osv +"ir.config_parameter" with key "database.uuid". +""" + +from osv import osv +import uuid + +class uuid_saver(osv.osv_memory): + """ An empty osv memory to init the uuid of the database the first it is + used. """ + + _name = 'maintenance.database_uuid_saver' + + def init(self, cr): + """ Checks that the database uuid was already created and create it if + it not the case. """ + params = self.pool.get('ir.config_parameter') + uniq = params.get_param(cr, 1, 'database.uuid') + if not uniq: + uniq = str(uuid.uuid1()) + params.set_param(cr, 1, 'database.uuid', uniq) + +uuid_saver() + diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py index f4f97a2c5f5..a6e10c71e3c 100644 --- a/bin/addons/base/maintenance/maintenance.py +++ b/bin/addons/base/maintenance/maintenance.py @@ -22,11 +22,13 @@ from osv import osv, fields import time import netsvc - from tools.misc import ustr from tools.translate import _ import tools.maintenance as tm +_nlogger = netsvc.Logger() +_CHAN = __name__.split()[-1] + class maintenance_contract(osv.osv): _name = "maintenance.contract" _description = "Maintenance Contract" @@ -35,6 +37,7 @@ class maintenance_contract(osv.osv): return [contract for contract in self.browse(cr, uid, self.search(cr, uid, [])) if contract.state == 'valid'] def status(self, cr, uid): + """ Method called by the client to check availability of maintenance contract. """ contracts = self._get_valid_contracts(cr, uid) return { 'status': "full" if contracts else "none" , @@ -42,6 +45,7 @@ class maintenance_contract(osv.osv): } def send(self, cr, uid, tb, explanations, remarks=None): + """ Method called by the client to send a problem to the maintenance server. """ if not remarks: remarks = "" @@ -63,7 +67,7 @@ class maintenance_contract(osv.osv): origin = 'client' dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid') - crm_case_id = rc.submit({ + crm_case_id = rc.submit_6({ 'contract_name': contract_name, 'tb': tb, 'explanations': explanations, @@ -73,11 +77,11 @@ class maintenance_contract(osv.osv): 'dbuuid': dbuuid}) except tm.RemoteContractException, rce: - netsvc.Logger().notifyChannel('maintenance', netsvc.LOG_INFO, rce) + _nlogger.notifyChannel(_CHAN, netsvc.LOG_INFO, rce) except osv.except_osv: raise except: - pass # don't want to throw exceptions in exception handler + pass # we don't want to throw exceptions in an exception handler if not crm_case_id: return False diff --git a/bin/tools/maintenance.py b/bin/tools/maintenance.py index 6789ac5f8f8..f0488b957ac 100644 --- a/bin/tools/maintenance.py +++ b/bin/tools/maintenance.py @@ -82,7 +82,7 @@ def remote_contract(cr, uid, contract_id): _logger.exception("Exception") raise RemoteContractException("Unable to contact the migration server") - info = ro.check_contract({ + info = ro.check_contract_6({ "contract_name": contract_id, "dbuuid": dbuuid, "dbname": cr.dbname}) From 469f0c3f5b80246aaa424779d5f5ac8136200e41 Mon Sep 17 00:00:00 2001 From: nvi-openerp Date: Thu, 18 Nov 2010 14:24:31 +0100 Subject: [PATCH 03/25] [IMP] wip bzr revid: nicolas.vanhoren@openerp.com-20101118132431-275gq1i1vjg52yoy --- bin/addons/base/maintenance/maintenance.py | 1 + bin/tools/maintenance.py | 3 -- bin/tools/ping.py | 40 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 bin/tools/ping.py diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py index a6e10c71e3c..b8e8e4dd6c7 100644 --- a/bin/addons/base/maintenance/maintenance.py +++ b/bin/addons/base/maintenance/maintenance.py @@ -31,6 +31,7 @@ _CHAN = __name__.split()[-1] class maintenance_contract(osv.osv): _name = "maintenance.contract" + _description = "Maintenance Contract" def _get_valid_contracts(self, cr, uid): diff --git a/bin/tools/maintenance.py b/bin/tools/maintenance.py index f0488b957ac..f8f8e9f11d3 100644 --- a/bin/tools/maintenance.py +++ b/bin/tools/maintenance.py @@ -21,10 +21,8 @@ import xmlrpclib import config -import logging import pooler -_logger = logging.getLogger(__name__) class RemoteConnectionException(Exception): pass @@ -79,7 +77,6 @@ def remote_contract(cr, uid, contract_id): config.config.get("maintenance_login"), config.config.get("maintenance_password") ).get_remote_object('maintenance.maintenance') except: - _logger.exception("Exception") raise RemoteContractException("Unable to contact the migration server") info = ro.check_contract_6({ diff --git a/bin/tools/ping.py b/bin/tools/ping.py new file mode 100644 index 00000000000..34efaad309a --- /dev/null +++ b/bin/tools/ping.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (). +# +# 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 . +# +############################################################################## + +import urllib +import pooler + +def send_ping(cr, uid): + pooler.get_pool(cr.dbname) + + args = urllib.urlencode({ + 'arg0': "coucou", + }) + uo = urllib.urlopen('http://localhost/phonehome/phonehome.php', args) + try: + submit_result = uo.read() + finally: + uo.close() + + return "" + + + From 5b2a35641cbac9c984df77d54c34fef0ae16e41b Mon Sep 17 00:00:00 2001 From: nvi-openerp Date: Thu, 18 Nov 2010 14:42:56 +0100 Subject: [PATCH 04/25] [IMP] wip bzr revid: nicolas.vanhoren@openerp.com-20101118134256-p0tlk3kbpw1njqu8 --- bin/addons/base/maintenance/maintenance.py | 4 ++++ bin/tools/config.py | 6 ++++++ bin/tools/ping.py | 7 ++++--- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py index b8e8e4dd6c7..0ddf8486e9f 100644 --- a/bin/addons/base/maintenance/maintenance.py +++ b/bin/addons/base/maintenance/maintenance.py @@ -25,6 +25,7 @@ import netsvc from tools.misc import ustr from tools.translate import _ import tools.maintenance as tm +import tools.ping _nlogger = netsvc.Logger() _CHAN = __name__.split()[-1] @@ -93,6 +94,9 @@ class maintenance_contract(osv.osv): for contract in self.browse(cr, uid, ids, context=context): res[contract.id] = ("unvalid", "valid")[contract.date_stop >= time.strftime('%Y-%m-%d')] return res + + def send_ping(self, cr, uid, context={}): + tools.ping.send_ping(cr, uid) _columns = { 'name' : fields.char('Contract ID', size=384, required=True, readonly=True), diff --git a/bin/tools/config.py b/bin/tools/config.py index 3e776d83135..50a127bc1b1 100644 --- a/bin/tools/config.py +++ b/bin/tools/config.py @@ -95,7 +95,11 @@ class configmanager(object): 'maintenance_db': 'tiny_belgium', 'maintenance_login': 'maintenance', 'maintenance_password': 'maintenance', + 'ping_url': 'http://tiny.my.odoo.com:8069/phonehome.php', } + + self.blacklist_for_save = set(['maintenance_server', 'maintenance_db', + 'maintenance_login', 'maintenance_password', "ping_url"]) self.misc = {} self.config_file = fname @@ -446,6 +450,8 @@ class configmanager(object): for opt in sorted(self.options.keys()): if opt in ('version', 'language', 'translate_out', 'translate_in', 'init', 'update'): continue + if opt in self.blacklist_for_save: + continue if opt in ('log_level', 'assert_exit_level'): p.set('options', opt, loglevelnames.get(self.options[opt], self.options[opt])) else: diff --git a/bin/tools/ping.py b/bin/tools/ping.py index 34efaad309a..dd45456fd02 100644 --- a/bin/tools/ping.py +++ b/bin/tools/ping.py @@ -21,20 +21,21 @@ import urllib import pooler +import config def send_ping(cr, uid): - pooler.get_pool(cr.dbname) + pool = pooler.get_pool(cr.dbname) args = urllib.urlencode({ 'arg0': "coucou", }) - uo = urllib.urlopen('http://localhost/phonehome/phonehome.php', args) + uo = urllib.urlopen(config.config.get("ping_url"), args) try: submit_result = uo.read() finally: uo.close() - return "" + return submit_result From 16e9bde2c82cd7d6b75748689589fb649f3dc837 Mon Sep 17 00:00:00 2001 From: nvi-openerp Date: Fri, 19 Nov 2010 09:15:50 +0100 Subject: [PATCH 05/25] [IMP] wip bzr revid: nicolas.vanhoren@openerp.com-20101119081550-0ftgvc1vurkumejl --- bin/addons/base/__openerp__.py | 1 + bin/addons/base/maintenance/maintenance.py | 101 ++++++++++-------- .../base/maintenance/maintenance_data.xml | 19 ++++ .../base/maintenance/maintenance_security.xml | 6 -- .../base/maintenance/maintenance_view.xml | 77 ++++--------- bin/tools/ping.py | 23 +++- 6 files changed, 113 insertions(+), 114 deletions(-) create mode 100644 bin/addons/base/maintenance/maintenance_data.xml delete mode 100644 bin/addons/base/maintenance/maintenance_security.xml diff --git a/bin/addons/base/__openerp__.py b/bin/addons/base/__openerp__.py index 492c397754d..73b428d805c 100644 --- a/bin/addons/base/__openerp__.py +++ b/bin/addons/base/__openerp__.py @@ -76,6 +76,7 @@ 'security/ir.model.access.csv', 'res/res_widget_view.xml', 'res/res_widget_data.xml', + 'maintenance/maintenance_data.xml', ], 'demo_xml': [ 'base_demo.xml', diff --git a/bin/addons/base/maintenance/maintenance.py b/bin/addons/base/maintenance/maintenance.py index 0ddf8486e9f..a109dea8021 100644 --- a/bin/addons/base/maintenance/maintenance.py +++ b/bin/addons/base/maintenance/maintenance.py @@ -26,6 +26,7 @@ from tools.misc import ustr from tools.translate import _ import tools.maintenance as tm import tools.ping +import datetime _nlogger = netsvc.Logger() _CHAN = __name__.split()[-1] @@ -95,63 +96,69 @@ class maintenance_contract(osv.osv): res[contract.id] = ("unvalid", "valid")[contract.date_stop >= time.strftime('%Y-%m-%d')] return res - def send_ping(self, cr, uid, context={}): - tools.ping.send_ping(cr, uid) + def check_validity(self, cr, uid, ids, context={}): + contract_id = ids[0] + contract = self.browse(cr, uid, contract_id) + valid = contract.state == "valid" + + self.send_ping(cr, uid, ids, cron_mode=False, context=context) + + contract = self.browse(cr, uid, contract_id) + valid2 = contract.state == "valid" + if not valid and not valid2: + raise osv.except_osv("Contract validation error", + "Please check your maintenance contract name and validity.") + + def send_ping(self, cr, uid, ids, cron_mode=True, context={}): + try: + result = tools.ping.send_ping(cr, uid) + except: + if cron_mode: + pass # if ping fails that's bad but we don't want it to interfere + else: + raise osv.except_osv("Error", "Error during communication with the maintenance server.") + + contracts = result["validity_dates"] + for contract in contracts: + c_id = self.search(cr, uid, [("name","=",contract)])[0] + date_from = contracts[contract][0] + date_to = contracts[contract][1] + valid = datetime.date.today() >= datetime.datetime.strptime(date_from, '%Y-%m-%d').date() \ + and datetime.date.today() <= datetime.datetime.strptime(date_to, '%Y-%m-%d').date() + self.write(cr, uid, c_id, { + "date_start": date_from, + "date_stop": date_to, + "state": "valid" if valid else "unvalid", + }) + + if cron_mode: + cronosv = self.pool.get("ir.cron") + sched_id = cronosv.search(cr, uid, [("name","=","Maintenance Update Scheduler")])[0] + cronosv.write(cr, uid, sched_id, { + "interval_type": result["interval_type"], + "interval_number": result["interval_number"], + }) + + return True _columns = { - 'name' : fields.char('Contract ID', size=384, required=True, readonly=True), + 'name' : fields.char('Contract ID', size=384, required=True), 'date_start' : fields.date('Starting Date', readonly=True), 'date_stop' : fields.date('Ending Date', readonly=True), - 'state' : fields.function(_valid_get, method=True, string="State", type="selection", selection=[('valid', 'Valid'),('unvalid', 'Unvalid')], readonly=True), - 'kind' : fields.char('Kind', size=64, required=True, readonly=True), + 'state' : fields.function(_valid_get, method=True, string="State", type="selection", + selection=[('valid', 'Valid'),('unvalid', 'Unvalid')], readonly=True), + 'kind' : fields.char('Kind', size=64, readonly=True), } + + _defaults = { + 'state': 'unvalid', + } + _sql_constraints = [ ('uniq_name', 'unique(name)', "Your maintenance contract is already subscribed in the system !") ] maintenance_contract() - -class maintenance_contract_wizard(osv.osv_memory): - _name = 'maintenance.contract.wizard' - - _columns = { - 'name' : fields.char('Contract ID', size=384, required=True ), - 'state' : fields.selection([('draft', 'Draft'),('validated', 'Validated'),('unvalidated', 'Unvalidated')], 'States'), - } - - _defaults = { - 'state' : lambda *a: 'draft', - } - - def action_validate(self, cr, uid, ids, context=None): - raise Exception("hahaha, this is a dirty exception to make you fail") - if not ids: - return False - contract = self.read(cr, uid, ids, ['name'])[0] - - try: - contract_info = tm.remote_contract(cr, uid, contract['name']) - except tm.RemoteContractException, rce: - raise osv.except_osv(_('Error'), ustr(rce)) - - if contract_info['status'] == "valid": - - self.pool.get('maintenance.contract').create( - cr, - uid, { - 'name' : contract['name'], - 'date_start' : contract_info['date_from'], - 'date_stop' : contract_info['date_to'], - 'kind' : contract_info['kind'], - } - ) - - return self.write(cr, uid, ids, - {'state' : ['validated' if contract_info['status'] == "valid" else 'unvalidated'] }, - context=context) - -maintenance_contract_wizard() - # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/bin/addons/base/maintenance/maintenance_data.xml b/bin/addons/base/maintenance/maintenance_data.xml new file mode 100644 index 00000000000..981a806bf0e --- /dev/null +++ b/bin/addons/base/maintenance/maintenance_data.xml @@ -0,0 +1,19 @@ + + + + + + Maintenance Update Scheduler + + + 1 + weeks + -1 + + + + + + + + \ No newline at end of file diff --git a/bin/addons/base/maintenance/maintenance_security.xml b/bin/addons/base/maintenance/maintenance_security.xml deleted file mode 100644 index 04b7d6dc2cf..00000000000 --- a/bin/addons/base/maintenance/maintenance_security.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/bin/addons/base/maintenance/maintenance_view.xml b/bin/addons/base/maintenance/maintenance_view.xml index fac95d705a3..5c3adbfc988 100644 --- a/bin/addons/base/maintenance/maintenance_view.xml +++ b/bin/addons/base/maintenance/maintenance_view.xml @@ -22,12 +22,25 @@ form
- - - - - - + + + + + + + + + + + + + +