[MERGE] refactor maintenance.contract into publisher_warranty.contract + add system logs scheduler

bzr revid: odo@openerp.com-20101208170350-p8tek7dk7wdtnzvb
This commit is contained in:
Nicolas Vanhoren 2010-12-08 18:03:50 +01:00 committed by Olivier Dony
commit 2c3cee033d
18 changed files with 627 additions and 433 deletions

View File

@ -18,3 +18,6 @@ bin/python2.6
build/
bin/yolk
bin/pil*.py
.project
.pydevproject
.settings

View File

@ -22,7 +22,7 @@
import ir
import module
import res
import maintenance
import publisher_warranty
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -71,11 +71,12 @@
'res/ir_property_view.xml',
'security/base_security.xml',
'maintenance/maintenance_view.xml',
'publisher_warranty/publisher_warranty_view.xml',
'security/ir.model.access.csv',
'res/res_widget_view.xml',
'res/res_widget_data.xml',
'publisher_warranty/publisher_warranty_data.xml',
],
'demo_xml': [
'base_demo.xml',

View File

@ -34,6 +34,7 @@ import ir_exports
import workflow
import ir_rule
import wizard
import ir_config_parameter
import osv_memory_autovacuum
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,101 @@
# -*- 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/>.
#
##############################################################################
"""
A module to store some configuration parameters relative to a whole database.
"""
from osv import osv,fields
import uuid
import datetime
from tools import misc
"""
A dictionary holding some configuration parameters to be initialized when the database is created.
"""
_default_parameters = {
"database.uuid": lambda: str(uuid.uuid1()),
"database.create_date": lambda: datetime.datetime.now().strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT),
}
class ir_config_parameter(osv.osv):
""" An osv to old configuration parameters for a given database.
To be short, it's just a global dictionary 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 init(self, cr):
"""
Initializes the parameters listed in _default_parameters.
"""
for key, func in _default_parameters.iteritems():
ids = self.search(cr, 1, [('key','=',key)])
if not ids:
self.set_param(cr, 1, key, func())
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()

View File

@ -144,7 +144,8 @@ class ir_cron(osv.osv, netsvc.Agent):
def restart(self, dbname):
self.cancel(dbname)
self._poolJobs(dbname)
# Reschedule cron processing job asap, but not in the current thread
self.setAlarm(self._poolJobs, time.time(), dbname, dbname)
def create(self, cr, uid, vals, context=None):
res = super(ir_cron, self).create(cr, uid, vals, context=context)

View File

@ -1,206 +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/>.
#
##############################################################################
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]
return {
'status': status,
'uncovered_modules': list(uncovered_modules),
}
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
valid_contracts = self._get_valid_contracts(cr, uid)
crm_case_id = None
rc = None
try:
for contract in valid_contracts:
rc = tm.remote_contract(contract.name, contract.password)
if rc.id:
break
rc = None
if not rc:
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)
except tm.RemoteContractException, rce:
netsvc.Logger().notifyChannel('maintenance', netsvc.LOG_INFO, rce)
except osv.except_osv:
raise
except:
pass
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
return True
def _valid_get(self, cr, uid, ids, field_name, arg, context=None):
res = {}
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
_columns = {
'name' : fields.char('Contract ID', size=256, required=True, readonly=True),
'password' : fields.char('Password', size=64, invisible=True, 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={} : '',
}
_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=256, required=True ),
'password' : fields.char('Password', size=64, 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):
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]
try:
contract_info = tm.remote_contract(contract['name'], contract['password'], modules)
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)
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)],
}
)
return self.write(cr, uid, ids, {'state' : ('unvalidated', 'validated')[is_ok] }, context=context)
maintenance_contract_wizard()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data noupdate="0">
</data>
</openerp>

View File

@ -1,131 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="maintenance_contract_tree_view" model="ir.ui.view">
<field name="name">maintenance.contract.tree</field>
<field name="model">maintenance.contract</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Maintenance Contract">
<field name="name"/>
<field name="date_start"/>
<field name="date_stop"/>
<field name="state" />
</tree>
</field>
</record>
<record id="maintenance_contract_form_view" model="ir.ui.view">
<field name="name">maintenance.contract.form</field>
<field name="model">maintenance.contract</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Maintenance Contract">
<group col="6" colspan="4">
<field name="name"/>
<field name="date_start"/>
<field name="date_stop"/>
</group>
<separator string="Covered Modules" colspan="4"/>
<field name="module_ids" nolabel="1" colspan="4">
<tree string="Covered Modules">
<field name="name" />
<field name="version" />
</tree>
</field>
<field name="state" colspan="4"/>
</form>
</field>
</record>
<record id="maintenance_contract_search_view" model="ir.ui.view">
<field name="name">maintenance.contract.search</field>
<field name="model">maintenance.contract</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Maintenance Contract">
<field name="name"/>
<field name="date_start"/>
<field name="date_stop"/>
</search>
</field>
</record>
<record id="maintenance_contract_view_calendar" model="ir.ui.view">
<field name="name">maintenance.contract.calendar</field>
<field name="model">maintenance.contract</field>
<field name="type">calendar</field>
<field name="arch" type="xml">
<calendar string="Maintenance Contract" date_start="date_start" color="state">
<field name="name"/>
<field name="state"/>
</calendar>
</field>
</record>
<record id="action_maintenance_contract_form" model="ir.actions.act_window">
<field name="name">Maintenance Contracts</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">maintenance.contract</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="search_view_id" ref="maintenance_contract_search_view"/>
</record>
<menuitem
name="Maintenance"
id="maintenance"
parent="base.menu_administration" groups="base.group_extended"/>
<menuitem
action="action_maintenance_contract_form"
id="menu_maintenance_contract"
parent="maintenance"/>
<record id="maintenance_contract_add_wizard" model="ir.ui.view">
<field name="name">maintenance.contract.add.wizard</field>
<field name="model">maintenance.contract.wizard</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Add Maintenance Contract" col="2">
<group col="1">
<separator string="Add Maintenance Contract" />
<group states="draft">
<field name="name" width="250" />
<newline />
<field name="password" password="True" />
<field name="state" invisible="1" />
</group>
<group states="validated">
<label string="Maintenance contract added !"/>
</group>
<group states="unvalidated">
<label string="Could you check your contract information ?" />
</group>
</group>
<group colspan="4">
<button type="object" string="_Cancel" icon="gtk-cancel" special="cancel" states="draft"/>
<button type="object" string="_Validate" icon="gtk-apply" name="action_validate" states="draft"/>
<button type="object" string="_Close" icon="gtk-close" special="cancel" states="validated,unvalidated"/>
</group>
</form>
</field>
</record>
<record id="action_maintenance_contract_add_wizard" model="ir.actions.act_window">
<field name="name">Add Maintenance Contract</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">maintenance.contract.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
action="action_maintenance_contract_add_wizard"
id="menu_maintenance_contract_add"
parent="maintenance" />
</data>
</openerp>

View File

@ -19,7 +19,7 @@
#
##############################################################################
import maintenance
import publisher_warranty
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,323 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 OpenERP S.A. (<http://www.openerp.com>).
#
# 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/>.
#
##############################################################################
"""
Module to handle publisher warranty contracts as well as notifications from
OpenERP.
"""
import datetime
import logging
import sys
import urllib
import urllib2
import pooler
import release
from osv import osv, fields
from tools.translate import _
from tools.safe_eval import safe_eval
from tools.config import config
from tools import misc
_logger = logging.getLogger(__name__)
"""
Time interval that will be used to determine up to which date we will
check the logs to see if a message we just received was already logged.
@type: datetime.timedelta
"""
_PREVIOUS_LOG_CHECK = datetime.timedelta(days=365)
class publisher_warranty_contract(osv.osv):
"""
Osv representing a publisher warranty contract.
"""
_name = "publisher_warranty.contract"
def _get_valid_contracts(self, cr, uid):
"""
Return the list of the valid contracts encoded in the system.
@return: A list of contracts
@rtype: list of publisher_warranty.contract browse records
"""
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 publisher warranty contract. """
contracts = self._get_valid_contracts(cr, uid)
return {
'status': "full" if contracts else "none" ,
'uncovered_modules': list(),
}
def send(self, cr, uid, tb, explanations, remarks=None):
""" Method called by the client to send a problem to the publisher warranty server. """
if not remarks:
remarks = ""
valid_contracts = self._get_valid_contracts(cr, uid)
valid_contract = valid_contracts[0]
try:
origin = 'client'
dbuuid = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
db_create_date = self.pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
msg = {'contract_name': valid_contract.name,
'tb': tb,
'explanations': explanations,
'remarks': remarks,
'origin': origin,
'dbname': cr.dbname,
'dbuuid': dbuuid,
'db_create_date': db_create_date}
add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
uo = urllib2.urlopen(config.get("publisher_warranty_url"),
urllib.urlencode({'arg0': msg, "action": "send",}),**add_arg)
try:
submit_result = uo.read()
finally:
uo.close()
result = safe_eval(submit_result)
crm_case_id = result
if not crm_case_id:
return False
except osv.except_osv:
raise
except Exception:
_logger.warning("Error sending problem report", exc_info=1)
raise osv.except_osv("Connection error", "An error occured during the connection " +
"with the publisher warranty server.")
return True
def check_validity(self, cr, uid, ids, context=None):
"""
Check the validity of a publisher warranty contract. This method just call get_logs() but checks
some more things, so it can be called from a user interface.
"""
contract_id = ids[0]
contract = self.browse(cr, uid, contract_id)
state = contract.state
validated = state != "unvalidated"
self.get_logs(cr, uid, ids, cron_mode=False, context=context)
contract = self.browse(cr, uid, contract_id)
validated2 = contract.state != "unvalidated"
if not validated and not validated2:
raise osv.except_osv(_("Contract validation error"),
_("Please check your publisher warranty contract name and validity."))
def get_logs(self, cr, uid, ids, cron_mode=True, context=None):
"""
Send a message to OpenERP's publisher warranty server to check the validity of
the contracts, get notifications, etc...
@param cron_mode: If true, catch all exceptions (appropriate for usage in a cron).
@type cron_mode: boolean
"""
try:
try:
result = get_sys_logs(cr, uid)
except Exception:
if cron_mode: # we don't want to see any stack trace in cron
return False
_logger.debug("Exception while sending a get logs messages", exc_info=1)
raise osv.except_osv(_("Error"), _("Error during communication with the publisher warranty server."))
contracts = result["contracts"]
for contract in contracts:
c_id = self.search(cr, uid, [("name","=",contract)])[0]
date_from = contracts[contract][0]
date_to = contracts[contract][1]
state = contracts[contract][2]
self.write(cr, uid, c_id, {
"date_start": date_from,
"date_stop": date_to,
"state": state,
})
limit_date = (datetime.datetime.now() - _PREVIOUS_LOG_CHECK).strftime(misc.DEFAULT_SERVER_DATETIME_FORMAT)
for message in result["messages"]:
ids = self.pool.get("res.log").search(cr, uid, [("res_model", "=", "publisher_warranty.contract"),
("create_date", ">=", limit_date),
("name", "=", message)])
if ids:
continue
self.pool.get('res.log').create(cr, uid,
{
'name': message,
'res_model': "publisher_warranty.contract",
"read": True,
"user_id": False,
},
context=context
)
except Exception:
if cron_mode:
return False # we don't want to see any stack trace in cron
else:
raise
return True
def get_last_user_messages(self, cr, uid, limit, context=None):
"""
Get the messages to be written in the web client.
@return: A list of html messages with ids, can be False or empty.
@rtype: list of tuples(int,string)
"""
ids = self.pool.get('res.log').search(cr, uid, [("res_model", "=", "publisher_warranty.contract")]
, order="create_date desc", limit=limit)
if not ids:
return []
messages = [(x.id, x.name) for x in self.pool.get('res.log').browse(cr, uid, ids)]
return messages
def del_user_message(self, cr, uid, id, context=None):
"""
Delete a message.
"""
self.pool.get('res.log').unlink(cr, uid, [id])
return True
_columns = {
'name' : fields.char('Serial Key', size=384, required=True),
'date_start' : fields.date('Starting Date', readonly=True),
'date_stop' : fields.date('Ending Date', readonly=True),
'state' : fields.selection([('unvalidated', 'Unvalidated'), ('valid', 'Valid')
, ('terminated', 'Terminated'), ('canceled', 'Canceled')], string="State", readonly=True),
'kind' : fields.char('Kind', size=64, readonly=True),
}
_defaults = {
'state': 'unvalidated',
}
_sql_constraints = [
('uniq_name', 'unique(name)', "Your publisher warranty contract is already subscribed in the system !")
]
publisher_warranty_contract()
class maintenance_contract(osv.osv_memory):
""" Old osv we only keep for compatibility with the clients. """
_name = "maintenance.contract"
def status(self, cr, uid):
return self.pool.get("publisher_warranty.contract").status(cr, uid)
def send(self, cr, uid, tb, explanations, remarks=None):
return self.pool.get("publisher_warranty.contract").send(cr, uid, tb, explanations, remarks)
maintenance_contract()
class publisher_warranty_contract_wizard(osv.osv_memory):
"""
A wizard osv to help people entering a publisher warranty contract.
"""
_name = 'publisher_warranty.contract.wizard'
_inherit = "ir.wizard.screen"
_columns = {
'name' : fields.char('Serial Key', size=256, required=True ),
'state' : fields.selection([("draft", "Draft"), ("finished", "Finished")])
}
_defaults = {
"state": "draft",
}
def action_validate(self, cr, uid, ids, context=None):
if not ids:
return False
wiz = self.browse(cr, uid, ids[0])
c_name = wiz.name
contract_osv = self.pool.get("publisher_warranty.contract")
contracts = contract_osv.search(cr, uid, [("name","=",c_name)])
if contracts:
raise osv.except_osv(_("Error"), _("That contract is already registered in the system."))
contract_id = contract_osv.create(cr, uid, {
"name": c_name,
"state": "unvalidated",
})
contract_osv.check_validity(cr, uid, [contract_id])
self.write(cr, uid, ids, {"state": "finished"})
return True
publisher_warranty_contract_wizard()
def get_sys_logs(cr, uid):
"""
Utility method to send a publisher warranty get logs messages.
"""
pool = pooler.get_pool(cr.dbname)
dbuuid = pool.get('ir.config_parameter').get_param(cr, uid, 'database.uuid')
db_create_date = pool.get('ir.config_parameter').get_param(cr, uid, 'database.create_date')
nbr_users = pool.get("res.users").search(cr, uid, [], count=True)
contractosv = pool.get('publisher_warranty.contract')
contracts = contractosv.browse(cr, uid, contractosv.search(cr, uid, []))
user = pool.get("res.users").browse(cr, uid, uid)
msg = {
"dbuuid": dbuuid,
"nbr_users": nbr_users,
"dbname": cr.dbname,
"db_create_date": db_create_date,
"version": release.version,
"contracts": [c.name for c in contracts],
"language": user.context_lang,
}
add_arg = {"timeout":30} if sys.version_info >= (2,6) else {}
uo = urllib2.urlopen(config.get("publisher_warranty_url"),
urllib.urlencode({'arg0': msg, "action": "update",}), **add_arg)
try:
submit_result = uo.read()
finally:
uo.close()
result = safe_eval(submit_result)
return result
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<record id="ir_cron_ping_scheduler" model="ir.cron">
<field name="name">Update System Logs</field>
<field eval="True" name="active" />
<field name="user_id" ref="base.user_root" />
<field name="interval_number">1</field>
<field name="interval_type">weeks</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall" />
<field eval="'publisher_warranty.contract'" name="model" />
<field eval="'get_logs'" name="function" />
<field eval="'(None,)'" name="args" />
<field name="priority">1000</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,146 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="publisher_warranty_contract_tree_view" model="ir.ui.view">
<field name="name">publisher_warranty.contract.tree</field>
<field name="model">publisher_warranty.contract</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Publisher Warranty Contracts">
<field name="name"/>
<field name="date_start"/>
<field name="date_stop"/>
<field name="state" />
</tree>
</field>
</record>
<record id="publisher_warranty_contract_form_view" model="ir.ui.view">
<field name="name">publisher_warranty.contract.form</field>
<field name="model">publisher_warranty.contract</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Publisher Warranty Contract">
<group col="2" colspan="4">
<group col="2">
<field name="name"/>
</group>
<group col="2">
<field name="date_start"/>
<field name="date_stop"/>
</group>
<group col="2">
<field name="state"/>
<field name="kind"/>
</group>
<group col="2">
<button name="check_validity" string="Validate" type="object"
attrs="{'invisible':[('state','in',['valid', 'terminated', 'canceled'])]}"/>
<button name="check_validity" string="Refresh Validation Dates" type="object"
attrs="{'invisible':[('state','in',['unvalidated'])]}"/>
</group>
</group>
</form>
</field>
</record>
<record id="publisher_warranty_contract_search_view" model="ir.ui.view">
<field name="name">publisher_warranty.contract.search</field>
<field name="model">publisher_warranty.contract</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="Publisher Warranty Contract">
<field name="name"/>
<field name="date_start"/>
<field name="date_stop"/>
</search>
</field>
</record>
<record id="publisher_warranty_contract_view_calendar" model="ir.ui.view">
<field name="name">publisher_warranty.contract.calendar</field>
<field name="model">publisher_warranty.contract</field>
<field name="type">calendar</field>
<field name="arch" type="xml">
<calendar string="Maintenance Contract" date_start="date_start" color="state">
<field name="name"/>
<field name="state"/>
</calendar>
</field>
</record>
<record id="action_publisher_warranty_contract_form" model="ir.actions.act_window">
<field name="name">Contracts</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">publisher_warranty.contract</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,calendar</field>
<field name="search_view_id" ref="publisher_warranty_contract_search_view"/>
</record>
<menuitem name="Publisher Warranty" id="publisher_warranty"
parent="base.menu_administration" groups="base.group_extended"/>
<menuitem action="action_publisher_warranty_contract_form" id="menu_publisher_warranty_contract"
parent="publisher_warranty" sequence="2"/>
<record id="publisher_warranty_contract_add_wizard" model="ir.ui.view">
<field name="name">publisher_warranty.contract.add.wizard</field>
<field name="model">publisher_warranty.contract.wizard</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Register a Contract">
<group col="8">
<group colspan="3" col="1">
<field name="config_logo" widget="image" width="220" height="130" nolabel="1" colspan="1"/>
<newline/>
<label width="220" string="This wizard helps you register a publisher warranty contract in your OpenERP system. After the contract has been registered, you will be able to send issues directly to OpenERP."/>
<label width="220"/>
<label width="220" string=""/>
<field name="state" invisible="1"/>
</group>
<separator orientation="vertical" rowspan="5"/>
<group colspan="4">
<separator string="Register a Contract" colspan="4"/>
<group states="draft" col="4">
<label string="Please enter the serial key provided in your contract document:" colspan="4"/>
<field name="name" colspan="4"/>
</group>
<group states="finished" col="4">
<label string="Publisher warranty contract successfully registered!" colspan="4"/>
</group>
</group>
<group colspan="8" col="8" states="draft">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Cancel" icon="gtk-cancel"/>
<button name="action_validate" string="Register" type="object" icon="gtk-apply"/>
</group>
<group colspan="8" col="8" states="finished">
<separator string="" colspan="8"/>
<label colspan="6" width="220"/>
<button special="cancel" string="Close" icon="gtk-ok"/>
</group>
</group>
</form>
</field>
</record>
<record id="action_publisher_warranty_contract_add_wizard" model="ir.actions.act_window">
<field name="name">Register a Contract</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">publisher_warranty.contract.wizard</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem
action="action_publisher_warranty_contract_add_wizard"
id="menu_publisher_warranty_contract_add"
parent="publisher_warranty" sequence="1"/>
</data>
</openerp>

View File

@ -20,24 +20,23 @@
##############################################################################
from osv import fields, osv
import tools
class res_log(osv.osv):
_name = 'res.log'
_columns = {
'name': fields.char('Message', size=128, help='The logging message.', required=True),
'user_id': fields.many2one('res.users','User', required=True),
'res_model': fields.char('Object', size=128),
'name': fields.char('Message', size=250, help='The logging message.', required=True, select=1),
'user_id': fields.many2one('res.users','User'),
'res_model': fields.char('Object', size=128, select=1),
'context': fields.char('Context', size=250),
'res_id': fields.integer('Object ID'),
'secondary': fields.boolean('Secondary Log', help='Do not display this log if it belongs to the same object the user is working on'),
'create_date': fields.datetime('Created Date', readonly=True),
'read': fields.boolean('Read', help="If this log item has been read, get() should not send it to the client")
'create_date': fields.datetime('Creation Date', readonly=True, select=1),
'read': fields.boolean('Read', help="If this log item has been read, get() should not send it to the client"),
}
_defaults = {
'user_id': lambda self,cr,uid,ctx: uid,
'context': "{}",
'read': False
'read': False,
}
_order='create_date desc'

View File

@ -11,6 +11,8 @@
<filter icon="terp-stock_align_left_24" string="Unread" domain="[('read','&lt;&gt;',True)]" name="unread"/>
<separator orientation="vertical"/>
<filter icon="terp-stock_align_left_24" string="My Logs" domain="[('user_id','=',uid)]" name="my"/>
<filter icon="terp-stock_align_left_24" string="System Logs"
domain="[('res_model','=','publisher_warranty.contract')]" name="sys"/>
<separator orientation="vertical"/>
<field name="name"/>
<field name="user_id"/>

View File

@ -112,8 +112,8 @@
"access_res_payterm_group_system","res_payterm_group_system","model_res_payterm","group_system",1,1,1,1
"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_publisher_warranty_group_user","publisher_warranty_contract group_user","model_publisher_warranty_contract","group_system",1,1,1,1
"access_publisher_warranty_all","publisher_warranty_contract all","model_publisher_warranty_contract",,1,0,0,0
"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 +123,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

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
112 access_res_payterm_group_system res_payterm_group_system model_res_payterm group_system 1 1 1 1
113 access_res_bank_group_partner_manager res_bank_group_partner_manager model_res_bank group_partner_manager 1 1 1 1
114 access_res_bank_user res_bank user model_res_bank group_user 1 0 0 0
115 access_maintenance_group_user access_publisher_warranty_group_user maintenance_contract group_user publisher_warranty_contract group_user model_maintenance_contract model_publisher_warranty_contract group_system 1 1 1 1
116 access_maintenance_contract_module access_publisher_warranty_all maintenance.contract.module publisher_warranty_contract all model_maintenance_contract_module model_publisher_warranty_contract group_system 1 1 0 1 0 1 0
117 access_multi_company_default user multi_company_default all model_multi_company_default 1 0 0 0
118 access_multi_company_default manager multi_company_default Manager model_multi_company_default group_erp_manager 1 1 1 1
119 access_ir_filter all ir_filters all model_ir_filters 1 0 0 0
123 access_res_widget res.widget model_res_widget group_erp_manager 1 1 1 1
124 access_res_widget_user res.widget.user model_res_widget 1 0 0 0
125 access_res_log_all res.log model_res_log 1 1 1 1
126 access_ir_config_parameter ir_config_parameter model_ir_config_parameter 1 0 0 0

View File

@ -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,7 +91,10 @@ class configmanager(object):
'static_http_url_prefix': None,
'secure_cert_file': 'server.cert',
'secure_pkey_file': 'server.pkey',
'publisher_warranty_url': 'http://services.openerp.com/publisher-warranty',
}
self.blacklist_for_save = set(["publisher_warranty_url"])
self.misc = {}
self.config_file = fname
@ -224,7 +227,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 +320,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 +377,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,16 +442,18 @@ 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 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:
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

View File

@ -1,69 +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 xmlrpclib
class RemoteContractException(Exception): pass
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"
rpc = xmlrpclib.ServerProxy(self.__server + 'common')
try:
self.__userid = rpc.login(self.__db, self.__login, self.__password)
except:
raise RemoteContractException("Unable to contact the migration server")
if not self.__userid:
raise RemoteContractException("Unable to contact the migration server")
self.__rpc = xmlrpclib.ServerProxy(self.__server + 'object')
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
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 remote_call
def __getitem__(self, item):
return getattr(self, item)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: