odoo/addons/audittrail/audittrail.py

93 lines
3.8 KiB
Python

# -*- coding :utf-8 -*-
from osv import osv, fields
import time, pooler, copy
class audittrail_rule(osv.osv):
_name = 'audittrail.rule'
_columns = {
"name": fields.char("Rule Name", size=32, required=True),
"object_id": fields.many2one('ir.model', 'Object', required=True),
"user_id": fields.many2many('res.users', 'audittail_rules_users', 'user_id', 'rule_id', 'Users'),
"log_read": fields.boolean("Log reads"),
"log_write": fields.boolean("Log writes"),
"log_unlink": fields.boolean("Log deletes"),
"log_create": fields.boolean("Log creates"),
"state": fields.selection((("draft", "Draft"),("subscribed", "Subscribed")), "State", required=True)
}
_defaults = {
'state': lambda *a: 'draft',
'log_create': lambda *a: 1,
'log_unlink': lambda *a: 1,
'log_write': lambda *a: 1,
}
__functions = {}
def subscribe(self, cr, uid, ids, *args):
for thisrule in self.browse(cr, uid, ids):
obj = self.pool.get(thisrule.object_id.model)
if not obj:
print ("%s WARNING:audittrail:%s is not part of the pool -- change audittrail depends -- setting rule: %s as DRAFT" % (time.strftime('%a, %d %b %Y %H:%M:%S'), thisrule.object_id.model, thisrule.name))
self.write(cr, uid, ids, {"state": "draft"})
return False
for field in ('read','write','create','unlink'):
if getattr(thisrule, 'log_'+field):
# backup corresponding method
self.__functions.setdefault(thisrule.id, [])
self.__functions[thisrule.id].append( (obj, field, getattr(obj,field)) )
uids_to_log = []
for user in thisrule.user_id:
uids_to_log.append(user.id)
# override it with the logging variant
setattr(obj, field, self.logging_fct(getattr(obj,field), thisrule.object_id, uids_to_log))
self.write(cr, uid, ids, {"state": "subscribed"})
return True
def logging_fct(self, fct_src, object, logged_uids):
if object.model=="audittrail.log":
return fct_src
def my_fct( cr, uid, *args, **args2):
if not len(logged_uids) or uid in logged_uids:
self.pool.get('audittrail.log').create(cr, uid, {"method": fct_src.__name__, "object_id": object.id, "user_id": uid, "args": "%s, %s" % (str(args), str(args2)), "name": "%s %s %s" % (fct_src.__name__, object.id, time.strftime("%Y-%m-%d %H:%M:%S"))})
return fct_src( cr, uid, *args, **args2)
return my_fct
def unsubscribe(self, cr, uid, ids, *args):
for thisrule in self.browse(cr, uid, ids):
for function in self.__functions[thisrule.id]:
setattr(function[0], function[1], function[2])
self.write(cr, uid, ids, {"state": "draft"})
return True
# def __init__(self, *args):
# super(audittrail_rule, self).__init__(*args)
# cr = pooler.db.cursor()
#FIXME: ah merde, ca craint pour le multi-db! Une solution serait d'overrider d'office toutes les methodes
# et de checker dans la methode elle meme s'il faut logger ou pas, mais ca risque de tout faire ramer violemment
# une autre solution (bien meilleure, il me semble) est de rajouter une méthode "db_dependant_init" dans osv qui est overridable
# et appellée dans le __init__ de osv (comme creation des tables et chargement des données)
# a merde, ca marche pas, vu que plusieurs utilisateurs peuvent etre sur des bases differentes en meme temps
# self.subscribe(cr, 1, self.search(cr, 1, [('state','=','subscribed')]))
# cr.commit()
# cr.close()
# del cr
class audittrail_log(osv.osv):
_name = 'audittrail.log'
_columns = {
"name": fields.char("Name", size=32),
"object_id": fields.many2one('ir.model', 'Object'),
"user_id": fields.many2one('res.users', 'User'),
"method": fields.selection((('read', 'Read'), ('write', 'Write'), ('unlink', 'Delete'), ('create', 'Create')), "Method"),
"args": fields.text("Arguments"),
"timestamp": fields.datetime("Timestamp")
}
_defaults = {
"timestamp": lambda *a: time.strftime("%Y-%m-%d %H:%M:%S")
}
audittrail_log()
audittrail_rule()