summaryrefslogtreecommitdiff
path: root/addons/web_editor/controllers
diff options
context:
space:
mode:
authorSébastien Theys <seb@odoo.com>2019-06-04 15:11:08 +0200
committerSébastien Theys <seb@odoo.com>2019-06-04 22:14:13 +0200
commit76cf2ae82a45b9ffcf63b524944a42b7f5192b0c (patch)
tree89540178c9e62def90377eb50ea8f7e1c089aff6 /addons/web_editor/controllers
parent191c556d6b50b35178ea5bb91fb998bcffb86367 (diff)
[IMP] web_editor, *: improve media dialog attachment upload
* = web_unsplash, website Remove iframe upload and replace it with a proper RPC. The route is now only accepting one file at a time, which makes it easier to maintain, and allows to process the first file as soon as it is ready, instead of having to wait on everything. Also fix a bug where a document could not be uploaded because it would try to parse it as an image. Remove filter after search result from the JS and add the corresponding conditions in the domain to avoid processing and returning unnecessary records. If multiple attachments exist with the same URL, now display them all to avoid confusion. Compute all the necessary values in the python model instead of in the JS. Allow SVG in the widget (the server already accepted them before). Disable multiple image upload when not in multiImages mode. task-1930726 PR: #31208
Diffstat (limited to 'addons/web_editor/controllers')
-rw-r--r--addons/web_editor/controllers/main.py134
1 files changed, 51 insertions, 83 deletions
diff --git a/addons/web_editor/controllers/main.py b/addons/web_editor/controllers/main.py
index 41bb7fceb54..85797ba2e23 100644
--- a/addons/web_editor/controllers/main.py
+++ b/addons/web_editor/controllers/main.py
@@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import base64
import io
-import json
import logging
import re
import time
@@ -11,7 +9,8 @@ from PIL import Image, ImageFont, ImageDraw
from lxml import etree
from odoo.http import request
-from odoo import http, tools
+from odoo import http, tools, _
+from odoo.exceptions import UserError
logger = logging.getLogger(__name__)
@@ -153,86 +152,21 @@ class Web_Editor(http.Controller):
return True
- #------------------------------------------------------
- # upload an image as base64
- #------------------------------------------------------
- @http.route('/web_editor/add_image_base64', type='json', auth='user', methods=['POST'], website=True)
- def add_image_base64(self, res_model, res_id, image_base64, filename, disable_optimization=None, **kwargs):
- attachment = self._image_to_attachment(res_model, res_id, image_base64, filename, filename, disable_optimization=disable_optimization)
- return attachment.read(['name', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'access_token'])[0]
-
- def _image_to_attachment(self, res_model, res_id, image_base64, name, datas_fname, disable_optimization=None):
- Attachments = request.env['ir.attachment']
+ @http.route('/web_editor/attachment/add_data', type='json', auth='user', methods=['POST'], website=True)
+ def add_data(self, name, data, disable_optimization=False, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
if not disable_optimization:
- image_base64 = tools.image_process(image_base64, verify_resolution=True)
- attachment = Attachments.create({
- 'name': name,
- 'datas_fname': datas_fname,
- 'datas': image_base64,
- 'public': res_model == 'ir.ui.view',
- 'res_id': res_id,
- 'res_model': res_model,
- })
- attachment.generate_access_token()
- return attachment
-
- #------------------------------------------------------
- # add attachment (images or link)
- #------------------------------------------------------
- @http.route('/web_editor/attachment/add', type='http', auth='user', methods=['POST'], website=True)
- def attach(self, upload=None, url=None, disable_optimization=None, filters=None, **kwargs):
- # the upload argument doesn't allow us to access the files if more than
- # one file is uploaded, as upload references the first file
- # therefore we have to recover the files from the request object
- Attachments = request.env['ir.attachment'] # registry for the attachment table
-
- res_model = kwargs.get('res_model', 'ir.ui.view')
- if res_model != 'ir.ui.view' and kwargs.get('res_id'):
- res_id = int(kwargs['res_id'])
- else:
- res_id = None
-
- uploads = []
- message = None
- if not upload: # no image provided, storing the link and the image name
- name = url.split("/").pop() # recover filename
- datas_fname = name
- if filters:
- datas_fname = filters + '_' + datas_fname
- attachment = Attachments.create({
- 'name': name,
- 'datas_fname': datas_fname,
- 'type': 'url',
- 'url': url,
- 'public': res_model == 'ir.ui.view',
- 'res_id': res_id,
- 'res_model': res_model,
- })
- attachment.generate_access_token()
- uploads += attachment.read(['name', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'access_token'])
- else: # images provided
try:
- attachments = request.env['ir.attachment']
- for c_file in request.httprequest.files.getlist('upload'):
- image_base64 = base64.b64encode(c_file.read())
- name = c_file.filename
- datas_fname = name
- if filters:
- datas_fname = filters + '_' + datas_fname
- attachments += self._image_to_attachment(res_model, res_id, image_base64, name, datas_fname, disable_optimization=disable_optimization)
- uploads += attachments.read(['name', 'mimetype', 'checksum', 'url', 'type', 'res_id', 'res_model', 'access_token'])
- except Exception as e:
- logger.exception("Failed to upload image to attachment")
- message = str(e)
-
- return """<script type='text/javascript'>
- window.attachments = %s;
- window.error = %s;
- </script>""" % (json.dumps(uploads), json.dumps(message))
+ data = tools.image_process(data, verify_resolution=True)
+ except OSError:
+ pass # not an image
+ attachment = self._attachment_create(name=name, data=data, res_id=res_id, res_model=res_model, filters=filters)
+ return attachment._get_media_info()
+
+ @http.route('/web_editor/attachment/add_url', type='json', auth='user', methods=['POST'], website=True)
+ def add_url(self, url, res_id=False, res_model='ir.ui.view', filters=False, **kwargs):
+ attachment = self._attachment_create(url=url, res_id=res_id, res_model=res_model, filters=filters)
+ return attachment._get_media_info()
- #------------------------------------------------------
- # remove attachment (images or link)
- #------------------------------------------------------
@http.route('/web_editor/attachment/remove', type='json', auth='user', website=True)
def remove(self, ids, **kwargs):
""" Removes a web-based image attachment if it is used by no view (template)
@@ -264,11 +198,12 @@ class Web_Editor(http.Controller):
attachments_to_remove.unlink()
return removal_blocked_by
- ## This route is used from CropImageDialog to get image info.
- ## It is used to display the original image when we crop a previously
- ## cropped image
@http.route('/web_editor/get_image_info', type='json', auth='user', website=True)
def get_image_info(self, image_id=None, xml_id=None):
+ """This route is used from CropImageDialog to get image info.
+ It is used to display the original image when we crop a previously
+ cropped image.
+ """
if xml_id:
record = request.env['ir.attachment'].get_attachment_by_key(xml_id)
elif image_id:
@@ -284,6 +219,39 @@ class Web_Editor(http.Controller):
result['originalSrc'] = record.url
return result
+ def _attachment_create(self, name='', data=False, url=False, res_id=False, res_model='ir.ui.view', filters=None):
+ """Create and return a new attachment."""
+ if not name and url:
+ name = url.split("/").pop()
+
+ if res_model != 'ir.ui.view' and res_id:
+ res_id = int(res_id)
+ else:
+ res_id = False
+
+ if filters:
+ name = filters + '_' + name
+
+ attachment_data = {
+ 'name': name,
+ 'public': res_model == 'ir.ui.view',
+ 'res_id': res_id,
+ 'res_model': res_model,
+ }
+
+ if data:
+ attachment_data['datas'] = data
+ elif url:
+ attachment_data.update({
+ 'type': 'url',
+ 'url': url,
+ })
+ else:
+ raise UserError(_("You need to specify either data or url to create an attachment."))
+
+ attachment = request.env['ir.attachment'].create(attachment_data)
+ return attachment
+
@http.route("/web_editor/get_assets_editor_resources", type="json", auth="user", website=True)
def get_assets_editor_resources(self, key, get_views=True, get_scss=True, get_js=True, bundles=False, bundles_restriction=[], only_user_custom_files=True):
"""