[FIX] web_editor: duplicate attachments in html field
Before this commit, when an image was cropped in a record on which multiple users were collaborating, multiple attachments would be created for the same image (one per user). Multiple attachments for the same image would also be created if the user uploaded the same image multiple times in the same record. This commit makes sure that, when about to create an attachment via the 'add_data', 'add_url' and 'modify_image' routes, if an attachment already exists for the same field values, the existing attachment is returned instead of creating a new one. task-3524601 closes odoo/odoo#148556 X-original-commit: 0e2508388fc03b2ea7a4033e571d289efa4ac479 Signed-off-by: Nicolas Bayet (nby) <nby@odoo.com>
This commit is contained in:
@@ -34,6 +34,26 @@ DEFAULT_LIBRARY_ENDPOINT = 'https://media-api.odoo.com'
|
||||
DEFAULT_OLG_ENDPOINT = 'https://olg.api.odoo.com'
|
||||
|
||||
|
||||
def get_existing_attachment(IrAttachment, vals):
|
||||
"""
|
||||
Check if an attachment already exists for the same vals. Return it if
|
||||
so, None otherwise.
|
||||
"""
|
||||
fields = dict(vals)
|
||||
# Falsy res_id defaults to 0 on attachment creation.
|
||||
fields['res_id'] = fields.get('res_id') or 0
|
||||
raw, datas = fields.pop('raw', None), fields.pop('datas', None)
|
||||
domain = [(field, '=', value) for field, value in fields.items()]
|
||||
if fields.get('type') == 'url':
|
||||
if 'url' not in fields:
|
||||
return None
|
||||
domain.append(('checksum', '=', False))
|
||||
else:
|
||||
if not (raw or datas):
|
||||
return None
|
||||
domain.append(('checksum', '=', IrAttachment._compute_checksum(raw or b64decode(datas))))
|
||||
return IrAttachment.search(domain, limit=1) or None
|
||||
|
||||
class Web_Editor(http.Controller):
|
||||
#------------------------------------------------------
|
||||
# convert font into picture
|
||||
@@ -355,7 +375,8 @@ class Web_Editor(http.Controller):
|
||||
if not attachment_data['public']:
|
||||
attachment.sudo().generate_access_token()
|
||||
else:
|
||||
attachment = IrAttachment.create(attachment_data)
|
||||
attachment = get_existing_attachment(IrAttachment, attachment_data) \
|
||||
or IrAttachment.create(attachment_data)
|
||||
|
||||
return attachment
|
||||
|
||||
@@ -530,7 +551,11 @@ class Web_Editor(http.Controller):
|
||||
fields['res_id'] = res_id
|
||||
if fields['mimetype'] == 'image/webp':
|
||||
fields['name'] = re.sub(r'\.(jpe?g|png)$', '.webp', fields['name'], flags=re.I)
|
||||
attachment = attachment.copy(fields)
|
||||
existing_attachment = get_existing_attachment(request.env['ir.attachment'], fields)
|
||||
if existing_attachment and not existing_attachment.url:
|
||||
attachment = existing_attachment
|
||||
else:
|
||||
attachment = attachment.copy(fields)
|
||||
if alt_data:
|
||||
for size, per_type in alt_data.items():
|
||||
reference_id = attachment.id
|
||||
|
||||
@@ -315,7 +315,7 @@ export class FileSelector extends Component {
|
||||
}
|
||||
|
||||
async onUploaded(attachment) {
|
||||
this.state.attachments = [attachment, ...this.state.attachments];
|
||||
this.state.attachments = [attachment, ...this.state.attachments.filter(attach => attach.id !== attachment.id)];
|
||||
this.selectAttachment(attachment);
|
||||
if (!this.props.multiSelect) {
|
||||
await this.props.save();
|
||||
|
||||
Reference in New Issue
Block a user