Browse Source

[ADD] module autovacuum_mail_message (#1208)

12.0-mig-module_prototyper_last
Florian 5 years ago
committed by Florian da Costa
parent
commit
5ea1234d19
  1. 66
      autovacuum_mail_message/README.rst
  2. 1
      autovacuum_mail_message/__init__.py
  3. 23
      autovacuum_mail_message/__openerp__.py
  4. 18
      autovacuum_mail_message/data/data.xml
  5. 170
      autovacuum_mail_message/i18n/fr.po
  6. 2
      autovacuum_mail_message/models/__init__.py
  7. 41
      autovacuum_mail_message/models/mail_message.py
  8. 73
      autovacuum_mail_message/models/message_vacuum_rule.py
  9. 2
      autovacuum_mail_message/security/ir.model.access.csv
  10. BIN
      autovacuum_mail_message/static/description/icon.png
  11. 5
      autovacuum_mail_message/tests/__init__.py
  12. 95
      autovacuum_mail_message/tests/test_message_vacuum_rule.py
  13. 52
      autovacuum_mail_message/views/message_rule_vacuum.xml

66
autovacuum_mail_message/README.rst

@ -0,0 +1,66 @@
.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:alt: License: LGPL-3
=======================
AutoVacuum Mail Message
=======================
Odoo create a lot of message and/or mails. With time it can slow the system or take a lot of disk space.
The goal of this module is to clean these message once they are obsolete.
Configuration
=============
* Go to the menu configuration => Technical => Email => Message vacuum Rule
* Add the adequates rules for your company. On each rule, you can indicate the models, type and subtypes for which you want to delete the messages, along with a retention time (in days).
* Activate the cron AutoVacuum Mails and Messages
It is recommanded to run it frequently and when the system is not very loaded.
(For instance : once a day, during the night.)
Usage
=====
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/149/9.0
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/server-tools/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smash it by providing detailed and welcomed feedback.
Credits
=======
Images
------
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
Contributors
------------
* Florian da Costa <florian.dacosta@akretion.com>
Do not contact contributors directly about support or help with technical issues.
Maintainer
----------
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.

1
autovacuum_mail_message/__init__.py

@ -0,0 +1 @@
from . import models

23
autovacuum_mail_message/__openerp__.py

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Akretion
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
{
"name": "AutoVacuum Mail Message",
"version": "9.0.1.0.0",
"category": "Tools",
"website": "https://github.com/OCA/server-tools",
"author": "Akretion, Odoo Community Association (OCA)",
"license": "LGPL-3",
"installable": True,
"application": False,
"summary": "Automatic Delete old mail message to clean database",
"depends": [
"mail",
],
"data": [
"data/data.xml",
"views/message_rule_vacuum.xml",
"security/ir.model.access.csv",
],
}

18
autovacuum_mail_message/data/data.xml

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo noupdate="1">
<record id="ir_cron_vacuum_message" model="ir.cron">
<field name="name">AutoVacuum Mails and Messages</field>
<field eval="False" name="active"/>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
<field eval="'mail.message'" name="model"/>
<field eval="'autovacuum_mail_message'" name="function"/>
<field eval="'()'" name="args"/>
</record>
</odoo>

170
autovacuum_mail_message/i18n/fr.po

@ -0,0 +1,170 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * autovacuum_mail_message
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 9.0c\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-29 11:30+0000\n"
"PO-Revision-Date: 2018-03-29 11:30+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: autovacuum_mail_message
#: selection:message.vacuum.rule,message_type:0
msgid "All"
msgstr "Tous"
#. module: autovacuum_mail_message
#: selection:message.vacuum.rule,message_type:0
msgid "Comment"
msgstr "Commentaires"
#. module: autovacuum_mail_message
#: model:ir.model,name:autovacuum_mail_message.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_company_id
msgid "Company"
msgstr "Société"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_create_uid
msgid "Created by"
msgstr "Créé par"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_create_date
msgid "Created on"
msgstr "Créé le"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_display_name
msgid "Display Name"
msgstr "Nom à afficher"
#. module: autovacuum_mail_message
#: selection:message.vacuum.rule,message_type:0
msgid "Email"
msgstr "Email"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_empty_subtype
msgid "Empty subtype"
msgstr "Sous-type Vide"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_id
msgid "ID"
msgstr "ID"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule___last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_write_uid
msgid "Last Updated by"
msgstr "Dernière modification par"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: autovacuum_mail_message
#: model:ir.model,name:autovacuum_mail_message.model_mail_message
msgid "Message"
msgstr "Message"
#. module: autovacuum_mail_message
#: model:ir.ui.view,arch_db:autovacuum_mail_message.message_vacuum_rule_form_view
msgid "Message Models"
msgstr "Documents des messages"
#. module: autovacuum_mail_message
#: model:ir.ui.view,arch_db:autovacuum_mail_message.message_vacuum_rule_form_view
msgid "Message Subtypes"
msgstr "Sous-types des messages"
#. module: autovacuum_mail_message
#: model:ir.actions.act_window,name:autovacuum_mail_message.action_message_vacuum_rule
#: model:ir.ui.menu,name:autovacuum_mail_message.menu_action_message_vacuum_rule
#: model:ir.ui.view,arch_db:autovacuum_mail_message.message_vacuum_rule_form_view
#: model:ir.ui.view,arch_db:autovacuum_mail_message.message_vacuum_rule_tree_view
msgid "Message Vacuum Rule"
msgstr "Règle de supression des messages"
#. module: autovacuum_mail_message
#: model:ir.model.fields,help:autovacuum_mail_message.field_message_vacuum_rule_message_subtype_ids
msgid "Message subtypes concerned by the rule. If left empty, the system won't take the subtype into account to find the messages to delete"
msgstr "Sous-types de message concernés par cette règle. Si c'est laissé vide, le système ne prendra pas en compte les sous type pour trouver les messages à supprimer"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_message_type
msgid "Message type"
msgstr "Type de message"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_model_ids
msgid "Models"
msgstr "Documents"
#. module: autovacuum_mail_message
#: model:ir.model.fields,help:autovacuum_mail_message.field_message_vacuum_rule_model_ids
msgid "Models concerned by the rule. If left empty, it will take all models into account"
msgstr "Documents concernés par la règle. Si c'est laissé vide, les messages de tous les modèles seront pris en compte"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_name
msgid "Name"
msgstr "Nom"
#. module: autovacuum_mail_message
#: model:ir.model.fields,help:autovacuum_mail_message.field_message_vacuum_rule_retention_time
msgid "Number of days the messages concerned by this rule will be keeped in the database after creation. Once the delay is passed, they will be automatically deleted."
msgstr "Nombre de jour de rétention des messages concerné par la règle. Une fois ce délai passé, les messages sont automatiquement supprimés"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_retention_time
msgid "Retention time"
msgstr "Temps de rétention"
#. module: autovacuum_mail_message
#: model:ir.model,name:autovacuum_mail_message.model_message_vacuum_rule
msgid "Rules Used to delete message historic"
msgstr "Règle de supression automatique de message"
#. module: autovacuum_mail_message
#: model:ir.model.fields,field_description:autovacuum_mail_message.field_message_vacuum_rule_message_subtype_ids
msgid "Subtypes"
msgstr "Sous-types"
#. module: autovacuum_mail_message
#: selection:message.vacuum.rule,message_type:0
msgid "System notification"
msgstr "Notification Système"
#. module: autovacuum_mail_message
#: model:ir.model.fields,help:autovacuum_mail_message.field_message_vacuum_rule_empty_subtype
msgid "Take also into account messages with no subtypes"
msgstr "Prend également en compte les messages sans aucun sous-type"
#. module: autovacuum_mail_message
#: code:addons/autovacuum_mail_message/models/message_vacuum_rule.py:47
#, python-format
msgid "The Retention Time can't be 0 days"
msgstr "Le temps de retention ne peut pas être de 0 jours."
#. module: autovacuum_mail_message
#: model:ir.model,name:autovacuum_mail_message.model_mail_message_subtype
msgid "mail_message_subtype"
msgstr "mail_message_subtype"

2
autovacuum_mail_message/models/__init__.py

@ -0,0 +1,2 @@
from . import mail_message
from . import message_vacuum_rule

41
autovacuum_mail_message/models/mail_message.py

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Akretion
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
import logging
import openerp
from openerp import api, models
_logger = logging.getLogger(__name__)
class MailMessage(models.Model):
_inherit = "mail.message"
@api.multi
def batch_unlink(self):
with api.Environment.manage():
with openerp.registry(
self.env.cr.dbname).cursor() as new_cr:
new_env = api.Environment(new_cr, self.env.uid,
self.env.context)
self = self.with_env(new_env)
try:
while self:
batch_delete_messages = self[0:1000]
self -= batch_delete_messages
batch_delete_messages.unlink()
new_env.cr.commit()
except Exception as e:
_logger.exception(
"Failed to delete messages : %s", str(e))
# Call by cron
@api.model
def autovacuum_mail_message(self):
rules = self.env['message.vacuum.rule'].search([])
for rule in rules:
domain = rule.get_message_domain()
messages = self.search(domain)
messages.batch_unlink()

73
autovacuum_mail_message/models/message_vacuum_rule.py

@ -0,0 +1,73 @@
# -*- coding: utf-8 -*-
# Copyright (C) 2018 Akretion
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from datetime import date, timedelta
from openerp import _, api, exceptions, fields, models
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
class MessageVacuumRule(models.Model):
_name = "message.vacuum.rule"
_description = "Rules Used to delete message historic"
name = fields.Char(required=True)
company_id = fields.Many2one(
'res.company', string="Company",
default=lambda self: self.env['res.company']._company_default_get(
'message.vacuum.rule'))
message_subtype_ids = fields.Many2many(
'mail.message.subtype', string="Subtypes",
help="Message subtypes concerned by the rule. If left empty, the "
"system won't take the subtype into account to find the "
"messages to delete")
empty_subtype = fields.Boolean(
help="Take also into account messages with no subtypes")
model_ids = fields.Many2many(
'ir.model', string="Models",
help="Models concerned by the rule. If left empty, it will take all "
"models into account")
message_type = fields.Selection([
('email', 'Email'),
('comment', 'Comment'),
('notification', 'System notification'),
('all', 'All')], required=True)
retention_time = fields.Integer(
required=True, default=365,
help="Number of days the messages concerned by this rule will be "
"keeped in the database after creation. Once the delay is "
"passed, they will be automatically deleted.")
@api.multi
@api.constrains('retention_time')
def retention_time_not_null(self):
for rule in self:
if not rule.retention_time:
raise exceptions.ValidationError(
_("The Retention Time can't be 0 days"))
@api.multi
def get_message_domain(self):
self.ensure_one()
today = date.today()
limit_date = today - timedelta(days=self.retention_time)
limit_date = limit_date.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
subtype_domain = []
if subtype_ids and self.empty_subtype:
subtype_domain = ['|', ('subtype_id', 'in', subtype_ids),
('subtype_id', '=', False)]
elif subtype_ids and not self.empty_subtype:
subtype_domain += [('subtype_id', 'in', subtype_ids)]
elif not subtype_ids and not self.empty_subtype:
subtype_domain += [('subtype_id', '!=', False)]
message_domain += subtype_domain
return message_domain

2
autovacuum_mail_message/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_full_message_vaccum_rule,access.full.message.vaccum.rule,model_message_vacuum_rule,base.group_system,1,1,1,1

BIN
autovacuum_mail_message/static/description/icon.png

After

Width: 128  |  Height: 128  |  Size: 9.2 KiB

5
autovacuum_mail_message/tests/__init__.py

@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2018 Akretion (Florian da Costa)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import test_message_vacuum_rule

95
autovacuum_mail_message/tests/test_message_vacuum_rule.py

@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-
# © 2018 Akretion (Florian da Costa)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import date, timedelta
from openerp import api, exceptions
from openerp.tests import common
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
class TestMessageVacuumRule(common.TransactionCase):
def create_mail_message(self, message_type, subtype):
vals = {
'message_type': message_type,
'subtype_id': subtype and subtype.id or False,
'date': self.before_400_days,
'model': 'mail.channel',
'res_id': self.env.ref('mail.channel_all_employees').id,
'subject': 'Test',
'body': 'Body Test',
}
return self.message_obj.create(vals)
def tearDown(self):
self.registry.leave_test_mode()
super(TestMessageVacuumRule, self).tearDown()
def setUp(self):
super(TestMessageVacuumRule, self).setUp()
self.registry.enter_test_mode()
self.env = api.Environment(self.registry.test_cr, self.env.uid,
self.env.context)
self.subtype = self.env.ref('mail.mt_comment')
self.message_obj = self.env['mail.message']
self.channel_model = self.env.ref('mail.model_mail_channel')
today = date.today()
before_400_days = today - timedelta(days=400)
self.before_400_days = before_400_days.strftime(
DEFAULT_SERVER_DATE_FORMAT)
def test_mail_vacuum_rules(self):
rule_vals = {
'name': 'Subtype Model',
'retention_time': 399,
'message_type': 'email',
'model_ids': [(6, 0, [self.channel_model.id])],
'message_subtype_ids': [(6, 0, [self.subtype.id])],
}
rule = self.env['message.vacuum.rule'].create(rule_vals)
m1 = self.create_mail_message('notification', self.subtype)
m2 = self.create_mail_message('email', self.env.ref('mail.mt_note'))
m3 = self.create_mail_message('email', False)
message_ids = [m1.id, m2.id, m3.id]
self.message_obj.autovacuum_mail_message()
message = self.message_obj.search(
[('id', 'in', message_ids)])
# no message deleted because either message_type is wrong or subtype
# is wront or subtype is empty
self.assertEqual(len(message),
3)
rule.write({'message_type': 'notification', 'retention_time': 405})
self.message_obj.autovacuum_mail_message()
message = self.message_obj.search(
[('id', 'in', message_ids)])
# no message deleted because of retention time
self.assertEqual(len(message),
3)
rule.write({'retention_time': 399})
self.message_obj.autovacuum_mail_message()
message = self.message_obj.search(
[('id', 'in', message_ids)])
self.assertEqual(len(message),
2)
rule.write({'message_type': 'email',
'message_subtype_ids': [(6, 0, [])],
'empty_subtype': True})
self.message_obj.autovacuum_mail_message()
message = self.message_obj.search(
[('id', 'in', message_ids)])
self.assertEqual(len(message),
0)
def test_retention_time_constraint(self):
rule_vals = {
'name': 'Subtype Model',
'retention_time': 0,
'message_type': 'email',
}
with self.assertRaises(exceptions.ValidationError):
self.env['message.vacuum.rule'].create(rule_vals)

52
autovacuum_mail_message/views/message_rule_vacuum.xml

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="message_vacuum_rule_form_view">
<field name="name">message.vacuum.rule.form.view</field>
<field name="model">message.vacuum.rule</field>
<field name="arch" type="xml">
<form string="Message Vacuum Rule">
<sheet>
<group>
<group col="4">
<field name="name" colspan="2"/>
<field name="company_id" colspan="2"/>
<field name="message_type" colspan="2"/>
<field name="empty_subtype" colspan="2"/>
<field name="retention_time" colspan="2"/>
</group>
<separator string="Message Models" colspan="4"/>
<field name="model_ids" nolabel="1" colspan="4"/>
<separator string="Message Subtypes" colspan="4"/>
<field name="message_subtype_ids" nolabel="1" colspan="4"/>
</group>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="message_vacuum_rule_tree_view">
<field name="name">message.vacuum.rule.form.view</field>
<field name="model">message.vacuum.rule</field>
<field name="arch" type="xml">
<tree>
<field name="name"/>
<field name="company_id"/>
<field name="message_type"/>
<field name="empty_subtype"/>
<field name="retention_time"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_message_vacuum_rule">
<field name="name">Message Vacuum Rule</field>
<field name="res_model">message.vacuum.rule</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem id="menu_action_message_vacuum_rule" parent="base.menu_email" action="action_message_vacuum_rule"/>
</odoo>
Loading…
Cancel
Save