From 1518a95f04dc8ae14fe6b873c256e96b40805d61 Mon Sep 17 00:00:00 2001 From: Enric Tobella Date: Tue, 21 Jan 2020 16:41:55 +0100 Subject: [PATCH] [REF] autovacuum_message_attachment: Improve the way we manage domains --- .../models/__init__.py | 1 + .../models/autovacuum_mixin.py | 30 +++++++- autovacuum_message_attachment/models/base.py | 13 ++++ .../models/ir_attachment.py | 20 ++++- .../models/mail_message.py | 26 ++++++- .../models/vacuum_rule.py | 76 ++++--------------- .../readme/CONTRIBUTORS.rst | 1 + .../views/rule_vacuum.xml | 47 +++++++----- 8 files changed, 126 insertions(+), 88 deletions(-) create mode 100644 autovacuum_message_attachment/models/base.py diff --git a/autovacuum_message_attachment/models/__init__.py b/autovacuum_message_attachment/models/__init__.py index 32b44bd3c..1093858b6 100644 --- a/autovacuum_message_attachment/models/__init__.py +++ b/autovacuum_message_attachment/models/__init__.py @@ -2,3 +2,4 @@ from . import autovacuum_mixin from . import ir_attachment from . import mail_message from . import vacuum_rule +from . import base diff --git a/autovacuum_message_attachment/models/autovacuum_mixin.py b/autovacuum_message_attachment/models/autovacuum_mixin.py index 6fe0f756e..ac4c6425c 100644 --- a/autovacuum_message_attachment/models/autovacuum_mixin.py +++ b/autovacuum_message_attachment/models/autovacuum_mixin.py @@ -5,6 +5,8 @@ import logging import odoo from odoo import api, models +from odoo.tools.safe_eval import safe_eval +import datetime _logger = logging.getLogger(__name__) @@ -40,6 +42,30 @@ class AutovacuumMixin(models.AbstractModel): def autovacuum(self, ttype='message'): rules = self.env['vacuum.rule'].search([('ttype', '=', ttype)]) for rule in rules: - domain = rule.get_domain() - records = self.search(domain) + records = rule._search_autovacuum_records() records.batch_unlink() + + def _get_autovacuum_domain(self, rule): + return [] + + def _get_autovacuum_records(self, rule): + if rule.model_id and rule.model_filter_domain: + return self._get_autovacuum_records_model(rule) + return self.search(self._get_autovacuum_domain(rule)) + + def _get_autovacuum_records_model(self, rule): + domain = self._get_autovacuum_domain(rule) + record_domain = safe_eval(rule.model_filter_domain, + locals_dict={'datetime': datetime}) + autovacuum_relation = self._autovacuum_relation + for leaf in domain: + if not isinstance(leaf, (tuple, list)): + record_domain.append(leaf) + continue + field, operator, value = leaf + record_domain.append( + ('%s.%s' % (autovacuum_relation, field), operator, value)) + records = self.env[rule.model_id.model].search(record_domain) + return self.search( + domain + [('res_id', 'in', records.ids)] + ) diff --git a/autovacuum_message_attachment/models/base.py b/autovacuum_message_attachment/models/base.py new file mode 100644 index 000000000..727ef9d2a --- /dev/null +++ b/autovacuum_message_attachment/models/base.py @@ -0,0 +1,13 @@ +# Copyright (C) 2019 Akretion +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class Base(models.AbstractModel): + _inherit = "base" + + attachment_ids = fields.One2many( + 'ir.attachment', 'res_id', string='Attachments', + domain=lambda self: [('res_model', '=', self._name)], auto_join=True + ) diff --git a/autovacuum_message_attachment/models/ir_attachment.py b/autovacuum_message_attachment/models/ir_attachment.py index c12cac548..20e343ca2 100644 --- a/autovacuum_message_attachment/models/ir_attachment.py +++ b/autovacuum_message_attachment/models/ir_attachment.py @@ -1,9 +1,27 @@ # Copyright (C) 2018 Akretion # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). -from odoo import models +from odoo import fields, models +from datetime import timedelta class IrAttachment(models.Model): _name = "ir.attachment" _inherit = ["ir.attachment", "autovacuum.mixin"] + _autovacuum_relation = 'attachment_ids' + + def _get_autovacuum_domain(self, rule): + domain = super()._get_autovacuum_domain(rule) + today = fields.Datetime.now() + limit_date = today - timedelta(days=rule.retention_time) + domain += [('create_date', '<', limit_date)] + if rule.filename_pattern: + domain += [('name', 'ilike', rule.filename_pattern)] + if rule.model_ids: + models = rule.model_ids.mapped('model') + domain += [('res_model', 'in', models)] + else: + # Avoid deleting attachment without model, if there are, it is + # probably some attachments created by Odoo + domain += [('res_model', '!=', False)] + return domain diff --git a/autovacuum_message_attachment/models/mail_message.py b/autovacuum_message_attachment/models/mail_message.py index 33825d90e..4940aad8c 100644 --- a/autovacuum_message_attachment/models/mail_message.py +++ b/autovacuum_message_attachment/models/mail_message.py @@ -1,10 +1,32 @@ -# -*- coding: utf-8 -*- # Copyright (C) 2018 Akretion # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). -from odoo import models +from odoo import fields, models +from datetime import timedelta class MailMessage(models.Model): _name = "mail.message" _inherit = ["mail.message", "autovacuum.mixin"] + _autovacuum_relation = 'message_ids' + + def _get_autovacuum_domain(self, rule): + domain = super()._get_autovacuum_domain(rule) + today = fields.Datetime.now() + limit_date = today - timedelta(days=rule.retention_time) + domain += [('date', '<', limit_date)] + if rule.message_type != 'all': + domain += [('message_type', '=', rule.message_type)] + if rule.model_ids: + models = rule.model_ids.mapped('model') + domain += [('model', 'in', models)] + subtype_ids = rule.message_subtype_ids.ids + if subtype_ids and rule.empty_subtype: + domain = [ + '|', ('subtype_id', 'in', subtype_ids), + ('subtype_id', '=', False)] + elif subtype_ids and not rule.empty_subtype: + domain += [('subtype_id', 'in', subtype_ids)] + elif not subtype_ids and not rule.empty_subtype: + domain += [('subtype_id', '!=', False)] + return domain diff --git a/autovacuum_message_attachment/models/vacuum_rule.py b/autovacuum_message_attachment/models/vacuum_rule.py index b662f4288..d3e87dd92 100644 --- a/autovacuum_message_attachment/models/vacuum_rule.py +++ b/autovacuum_message_attachment/models/vacuum_rule.py @@ -1,12 +1,7 @@ # Copyright (C) 2018 Akretion # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). -from datetime import date, timedelta - from odoo import _, api, exceptions, fields, models -from odoo.tools import DEFAULT_SERVER_DATE_FORMAT -from odoo.tools.safe_eval import safe_eval -import datetime class VacuumRule(models.Model): @@ -19,8 +14,10 @@ class VacuumRule(models.Model): for rule in self: if rule.model_ids and len(rule.model_ids) == 1: rule.model_id = rule.model_ids.id + rule.model = rule.model_id.model else: rule.model_id = False + rule.model = False name = fields.Char(required=True) ttype = fields.Selection( @@ -53,6 +50,11 @@ class VacuumRule(models.Model): "domain, etc...for other fields, like the domain filter") model_filter_domain = fields.Text( string='Model Filter Domain') + model = fields.Char( + readonly=True, + compute='_get_model_id', + string='Model code' + ) message_type = fields.Selection([ ('email', 'Email'), ('comment', 'Comment'), @@ -74,61 +76,11 @@ class VacuumRule(models.Model): raise exceptions.ValidationError( _("The Retention Time can't be 0 days")) - @api.multi - def _get_message_domain(self): - today = date.today() - limit_date = (today - timedelta(days=self.retention_time)).strftime( - DEFAULT_SERVER_DATE_FORMAT) - message_domain = [('date', '<', limit_date)] - if self.message_type != 'all': - message_domain += [('message_type', '=', self.message_type)] - if self.model_ids: - models = self.model_ids.mapped('model') - message_domain += [('model', 'in', models)] - - subtype_ids = self.message_subtype_ids.ids - if subtype_ids and self.empty_subtype: - message_domain = ['|', ('subtype_id', 'in', subtype_ids), - ('subtype_id', '=', False)] - elif subtype_ids and not self.empty_subtype: - message_domain += [('subtype_id', 'in', subtype_ids)] - elif not subtype_ids and not self.empty_subtype: - message_domain += [('subtype_id', '!=', False)] - return message_domain - - @api.multi - def _get_attachment_domain(self): - today = date.today() - limit_date = (today - timedelta(days=self.retention_time)).strftime( - DEFAULT_SERVER_DATE_FORMAT) - attachment_domain = [('create_date', '<', limit_date)] - if self.filename_pattern: - attachment_domain += [('name', 'ilike', self.filename_pattern)] - if self.model_ids: - models = self.model_ids.mapped('model') - attachment_domain += [('res_model', 'in', models)] - else: - # Avoid deleting attachment without model, if there are, it is - # probably some attachments created by Odoo - attachment_domain += [('res_model', '!=', False)] - return attachment_domain - - @api.multi - def get_domain(self): + def _search_autovacuum_records(self): self.ensure_one() - domain = [] - if self.ttype == 'message': - domain += self._get_message_domain() - elif self.ttype == 'attachment': - domain += self._get_attachment_domain() - - # Case we want a condition on linked model records - if self.model_id and self.model_filter_domain: - record_domain = safe_eval(self.model_filter_domain, - locals_dict={'datetime': datetime}) - - res_ids = self.env[self.model_id.model].with_context( - active_test=False).search(record_domain).ids - domain += ['|', ('res_id', 'in', res_ids), - ('res_id', '=', False)] - return domain + model = self.ttype + if model == 'message': + model = 'mail.message' + elif model == 'attachment': + model = 'ir.attachment' + return self.env[model]._get_autovacuum_records(self) diff --git a/autovacuum_message_attachment/readme/CONTRIBUTORS.rst b/autovacuum_message_attachment/readme/CONTRIBUTORS.rst index 0bddb053a..8d20627d8 100644 --- a/autovacuum_message_attachment/readme/CONTRIBUTORS.rst +++ b/autovacuum_message_attachment/readme/CONTRIBUTORS.rst @@ -1 +1,2 @@ * Florian da Costa +* Enric Tobella diff --git a/autovacuum_message_attachment/views/rule_vacuum.xml b/autovacuum_message_attachment/views/rule_vacuum.xml index 68194e7b1..578a74392 100644 --- a/autovacuum_message_attachment/views/rule_vacuum.xml +++ b/autovacuum_message_attachment/views/rule_vacuum.xml @@ -8,30 +8,35 @@
- - - - - - - + + + + + + + - - - - - + + + - - + + + + + + + + + + + + + + + + - - - - - - -