[REF] web_editor: move handle_history_divergence in tools.py

As `handle_history_divergence` is not used in the controllers, it makes
no sense to have it in `controllers/main.py`.

task-3217965

closes odoo/odoo#136277

Signed-off-by: David Monjoie (dmo) <dmo@odoo.com>
This commit is contained in:
Nicolas Bayet
2023-09-27 14:57:13 +00:00
parent 1eb32c94b4
commit 1d70293093
4 changed files with 58 additions and 53 deletions
+1 -1
View File
@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, fields, models, _
from odoo.addons.web_editor.controllers.main import handle_history_divergence
from odoo.addons.web_editor.tools import handle_history_divergence
class Job(models.Model):
+1 -1
View File
@@ -8,7 +8,7 @@ from datetime import timedelta, datetime, time
from odoo import api, Command, fields, models, tools, SUPERUSER_ID, _, _lt
from odoo.addons.rating.models import rating_data
from odoo.addons.web_editor.controllers.main import handle_history_divergence
from odoo.addons.web_editor.tools import handle_history_divergence
from odoo.exceptions import UserError, ValidationError, AccessError
from odoo.osv import expression
from odoo.tools.misc import get_lang
-51
View File
@@ -31,57 +31,6 @@ from ..models.ir_attachment import SUPPORTED_IMAGE_MIMETYPES
logger = logging.getLogger(__name__)
DEFAULT_LIBRARY_ENDPOINT = 'https://media-api.odoo.com'
diverging_history_regex = 'data-last-history-steps="([0-9,]+)"'
# This method must be called in a context that has write access to the record as
# it will write to the bus.
def handle_history_divergence(record, html_field_name, vals):
# Do not handle history divergence if the field is not in the values.
if html_field_name not in vals:
return
incoming_html = vals[html_field_name]
incoming_history_matches = re.search(diverging_history_regex, incoming_html or '')
# When there is no incoming history id, it means that the value does not
# comes from the odoo editor or the collaboration was not activated. In
# project, it could come from the collaboration pad. In that case, we do not
# handle history divergences.
if request:
channel = (request.db, 'editor_collaboration', record._name, html_field_name, record.id)
if incoming_history_matches is None:
if request:
bus_data = {
'model_name': record._name,
'field_name': html_field_name,
'res_id': record.id,
'notificationName': 'html_field_write',
'notificationPayload': {'last_step_id': None},
}
request.env['bus.bus']._sendone(channel, 'editor_collaboration', bus_data)
return
incoming_history_ids = incoming_history_matches[1].split(',')
last_step_id = incoming_history_ids[-1]
bus_data = {
'model_name': record._name,
'field_name': html_field_name,
'res_id': record.id,
'notificationName': 'html_field_write',
'notificationPayload': {'last_step_id': last_step_id},
}
if request:
request.env['bus.bus']._sendone(channel, 'editor_collaboration', bus_data)
if record[html_field_name]:
server_history_matches = re.search(diverging_history_regex, record[html_field_name] or '')
# Do not check old documents without data-last-history-steps.
if server_history_matches:
server_last_history_id = server_history_matches[1].split(',')[-1]
if server_last_history_id not in incoming_history_ids:
logger.warning('The document was already saved from someone with a different history for model %r, field %r with id %r.', record._name, html_field_name, record.id)
raise ValidationError(_('The document was already saved from someone with a different history for model %r, field %r with id %r.', record._name, html_field_name, record.id))
# Save only the latest id.
vals[html_field_name] = incoming_html[0:incoming_history_matches.start(1)] + last_step_id + incoming_html[incoming_history_matches.end(1):]
class Web_Editor(http.Controller):
#------------------------------------------------------
+56
View File
@@ -3,6 +3,7 @@
import base64
import contextlib
import logging
import re
import requests
@@ -10,8 +11,12 @@ from markupsafe import Markup
from werkzeug.urls import url_encode
from odoo import _
from odoo.exceptions import ValidationError
from odoo.http import request
from odoo.tools import image_process
logger = logging.getLogger(__name__)
# To detect if we have a valid URL or not
valid_url_regex = r'^(http://|https://|//)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(/.*)?$'
@@ -159,3 +164,54 @@ def get_video_thumbnail(video_url):
if response and response.ok:
return image_process(response.content)
return None
diverging_history_regex = 'data-last-history-steps="([0-9,]+)"'
# This method must be called in a context that has write access to the record as
# it will write to the bus.
def handle_history_divergence(record, html_field_name, vals):
# Do not handle history divergence if the field is not in the values.
if html_field_name not in vals:
return
incoming_html = vals[html_field_name]
incoming_history_matches = re.search(diverging_history_regex, incoming_html or '')
# When there is no incoming history id, it means that the value does not
# comes from the odoo editor or the collaboration was not activated. In
# project, it could come from the collaboration pad. In that case, we do not
# handle history divergences.
if request:
channel = (request.db, 'editor_collaboration', record._name, html_field_name, record.id)
if incoming_history_matches is None:
if request:
bus_data = {
'model_name': record._name,
'field_name': html_field_name,
'res_id': record.id,
'notificationName': 'html_field_write',
'notificationPayload': {'last_step_id': None},
}
request.env['bus.bus']._sendone(channel, 'editor_collaboration', bus_data)
return
incoming_history_ids = incoming_history_matches[1].split(',')
last_step_id = incoming_history_ids[-1]
bus_data = {
'model_name': record._name,
'field_name': html_field_name,
'res_id': record.id,
'notificationName': 'html_field_write',
'notificationPayload': {'last_step_id': last_step_id},
}
if request:
request.env['bus.bus']._sendone(channel, 'editor_collaboration', bus_data)
if record[html_field_name]:
server_history_matches = re.search(diverging_history_regex, record[html_field_name] or '')
# Do not check old documents without data-last-history-steps.
if server_history_matches:
server_last_history_id = server_history_matches[1].split(',')[-1]
if server_last_history_id not in incoming_history_ids:
logger.warning('The document was already saved from someone with a different history for model %r, field %r with id %r.', record._name, html_field_name, record.id)
raise ValidationError(_('The document was already saved from someone with a different history for model %r, field %r with id %r.', record._name, html_field_name, record.id))
# Save only the latest id.
vals[html_field_name] = incoming_html[0:incoming_history_matches.start(1)] + last_step_id + incoming_html[incoming_history_matches.end(1):]