Skip to content

Commit 3d59cc8

Browse files
committed
[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 #99856 Signed-off-by: Raphael Collet <rco@odoo.com>
1 parent 27cd3c0 commit 3d59cc8

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

addons/attachment_indexation/models/ir_attachment.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import zipfile
77

88
from odoo import api, models
9+
from odoo.tools.lru import LRU
910

1011
_logger = logging.getLogger(__name__)
1112

@@ -21,6 +22,8 @@
2122
FTYPES = ['docx', 'pptx', 'xlsx', 'opendoc', 'pdf']
2223

2324

25+
index_content_cache = LRU(1)
26+
2427
def textToString(element):
2528
buff = u""
2629
for node in element.childNodes:
@@ -121,10 +124,19 @@ def _index_pdf(self, bin_data):
121124
return buf
122125

123126
@api.model
124-
def _index(self, bin_data, mimetype):
127+
def _index(self, bin_data, mimetype, checksum=None):
128+
if checksum:
129+
cached_content = index_content_cache.get(checksum)
130+
if cached_content:
131+
return cached_content
132+
res = False
125133
for ftype in FTYPES:
126134
buf = getattr(self, '_index_%s' % ftype)(bin_data)
127135
if buf:
128-
return buf.replace('\x00', '')
136+
res = buf.replace('\x00', '')
137+
break
129138

130-
return super(IrAttachment, self)._index(bin_data, mimetype)
139+
res = res or super(IrAttachment, self)._index(bin_data, mimetype, checksum=checksum)
140+
if checksum:
141+
index_content_cache[checksum] = res
142+
return res

odoo/addons/base/models/ir_attachment.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,15 @@ def _set_attachment_data(self, asbytes):
232232
self._file_delete(fname)
233233

234234
def _get_datas_related_values(self, data, mimetype):
235+
checksum = self._compute_checksum(data)
236+
try:
237+
index_content = self._index(data, mimetype, checksum=checksum)
238+
except TypeError:
239+
index_content = self._index(data, mimetype)
235240
values = {
236241
'file_size': len(data),
237-
'checksum': self._compute_checksum(data),
238-
'index_content': self._index(data, mimetype),
242+
'checksum': checksum,
243+
'index_content': index_content,
239244
'store_fname': False,
240245
'db_datas': data,
241246
}
@@ -338,7 +343,7 @@ def _check_contents(self, values):
338343
return values
339344

340345
@api.model
341-
def _index(self, bin_data, file_type):
346+
def _index(self, bin_data, file_type, checksum=None):
342347
""" compute the index content of the given binary data.
343348
This is a python implementation of the unix command 'strings'.
344349
:param bin_data : datas in binary form
@@ -609,7 +614,7 @@ def create(self, vals_list):
609614
))
610615

611616
# 'check()' only uses res_model and res_id from values, and make an exists.
612-
# We can group the values by model, res_id to make only one query when
617+
# We can group the values by model, res_id to make only one query when
613618
# creating multiple attachments on a single record.
614619
record_tuple = (values.get('res_model'), values.get('res_id'))
615620
record_tuple_set.add(record_tuple)

0 commit comments

Comments
 (0)