[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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user