[FIX] base: avoid indexing attachment on copy

When sending a mass mailing with a pdf attachment, the ir.attachment
is copied in the mail.composer for each email. Spending time and
resources in the indexing of the pdf. On copy that value is already in
the vals. This is especially true when attachment_indexation is
installed, processing the pdf documents can be costly with pdfminer.

It could also be done by overwriting the copu from ir_attachment but it
could happen a misuse of mass create of ir.attachment with the same file
has the same issue

closes odoo/odoo#100374

X-original-commit: 3d59cc849ed1040c08c4d1488866ba78c80990c8
Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
Stanislas Sobieski
2022-09-17 00:51:32 +02:00
parent c31a159b4e
commit 82e8c74f1e
2 changed files with 24 additions and 7 deletions
@@ -6,6 +6,7 @@ import xml.dom.minidom
import zipfile
from odoo import api, models
from odoo.tools.lru import LRU
_logger = logging.getLogger(__name__)
@@ -21,6 +22,8 @@ except ImportError:
FTYPES = ['docx', 'pptx', 'xlsx', 'opendoc', 'pdf']
index_content_cache = LRU(1)
def textToString(element):
buff = u""
for node in element.childNodes:
@@ -121,10 +124,19 @@ class IrAttachment(models.Model):
return buf
@api.model
def _index(self, bin_data, mimetype):
def _index(self, bin_data, mimetype, checksum=None):
if checksum:
cached_content = index_content_cache.get(checksum)
if cached_content:
return cached_content
res = False
for ftype in FTYPES:
buf = getattr(self, '_index_%s' % ftype)(bin_data)
if buf:
return buf.replace('\x00', '')
res = buf.replace('\x00', '')
break
return super(IrAttachment, self)._index(bin_data, mimetype)
res = res or super(IrAttachment, self)._index(bin_data, mimetype, checksum=checksum)
if checksum:
index_content_cache[checksum] = res
return res
+9 -4
View File
@@ -251,10 +251,15 @@ class IrAttachment(models.Model):
self._file_delete(fname)
def _get_datas_related_values(self, data, mimetype):
checksum = self._compute_checksum(data)
try:
index_content = self._index(data, mimetype, checksum=checksum)
except TypeError:
index_content = self._index(data, mimetype)
values = {
'file_size': len(data),
'checksum': self._compute_checksum(data),
'index_content': self._index(data, mimetype),
'checksum': checksum,
'index_content': index_content,
'store_fname': False,
'db_datas': data,
}
@@ -360,7 +365,7 @@ class IrAttachment(models.Model):
return values
@api.model
def _index(self, bin_data, file_type):
def _index(self, bin_data, file_type, checksum=None):
""" compute the index content of the given binary data.
This is a python implementation of the unix command 'strings'.
:param bin_data : datas in binary form
@@ -652,7 +657,7 @@ class IrAttachment(models.Model):
))
# 'check()' only uses res_model and res_id from values, and make an exists.
# We can group the values by model, res_id to make only one query when
# We can group the values by model, res_id to make only one query when
# creating multiple attachments on a single record.
record_tuple = (values.get('res_model'), values.get('res_id'))
record_tuple_set.add(record_tuple)