[FIX] web_editor: enable embedding unlisted vimeo videos

When the user inserts a video with the `/video` command and provides a
link of an unlisted vimeo video, the system generates a new url based
on the options selected but omits the hash parameter granting access to
the given video. As a result, the video can not be loaded and the vimeo
`iframe` indicates that the video does not exist.

To fix the issue, we will copy the hash parameter from the original link
to the newly generated url. That way, the video will be loaded properly
and the user will be able to embed unlisted vimeo videos.

Steps to reproduce the issue:
1. Install the website app
2. Open the website builder
3. Drag and drop a text block
4. In the text block, type the `/video` command to insert a video
5. In the modal, paste the link of an unlisted video
6. The `iframe` indicates that the video does not exist

=> The system should extract the hash parameter from the provided url
and set it on the generated url. The video should then be loaded properly.

task-3697764

closes odoo/odoo#157279

X-original-commit: f72b873e58348374f3ce0e91ec5e87ed42215e55
Signed-off-by: Warnon Aurélien (awa) <awa@odoo.com>
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Julien Banken
2024-03-20 13:52:19 +00:00
parent c029167cca
commit ca76366bac
2 changed files with 47 additions and 5 deletions
+33 -2
View File
@@ -12,6 +12,9 @@ class TestVideoUtils(common.BaseCase):
urls = {
'youtube': 'https://www.youtube.com/watch?v=xCvFZrrQq7k',
'vimeo': 'https://vimeo.com/395399735',
'vimeo_unlisted_video': 'https://vimeo.com/795669787/0763fdb816',
'vimeo_player': 'https://player.vimeo.com/video/395399735',
'vimeo_player_unlisted_video': 'https://player.vimeo.com/video/795669787?h=0763fdb816',
'dailymotion': 'https://www.dailymotion.com/video/x7svr6t',
'youku': 'https://v.youku.com/v_show/id_XMzY1MjY4.html?spm=a2hzp.8244740.0.0',
'instagram': 'https://www.instagram.com/p/B6dXGTxggTG/',
@@ -29,6 +32,9 @@ class TestVideoUtils(common.BaseCase):
self.assertIsNotNone(re.search(tools.player_regexes['youtube'], TestVideoUtils.urls['youtube']))
#vimeo
self.assertIsNotNone(re.search(tools.player_regexes['vimeo'], TestVideoUtils.urls['vimeo']))
self.assertIsNotNone(re.search(tools.player_regexes['vimeo'], TestVideoUtils.urls['vimeo_unlisted_video']))
self.assertIsNotNone(re.search(tools.player_regexes['vimeo_player'], TestVideoUtils.urls['vimeo_player']))
self.assertIsNotNone(re.search(tools.player_regexes['vimeo_player'], TestVideoUtils.urls['vimeo_player_unlisted_video']))
#dailymotion
self.assertIsNotNone(re.search(tools.player_regexes['dailymotion'], TestVideoUtils.urls['dailymotion']))
#youku
@@ -44,6 +50,12 @@ class TestVideoUtils(common.BaseCase):
#vimeo
self.assertEqual('vimeo', tools.get_video_source_data(TestVideoUtils.urls['vimeo'])[0])
self.assertEqual('395399735', tools.get_video_source_data(TestVideoUtils.urls['vimeo'])[1])
self.assertEqual('vimeo', tools.get_video_source_data(TestVideoUtils.urls['vimeo_unlisted_video'])[0])
self.assertEqual('795669787', tools.get_video_source_data(TestVideoUtils.urls['vimeo_unlisted_video'])[1])
self.assertEqual('vimeo', tools.get_video_source_data(TestVideoUtils.urls['vimeo_player'])[0])
self.assertEqual('395399735', tools.get_video_source_data(TestVideoUtils.urls['vimeo_player'])[1])
self.assertEqual('vimeo', tools.get_video_source_data(TestVideoUtils.urls['vimeo_player_unlisted_video'])[0])
self.assertEqual('795669787', tools.get_video_source_data(TestVideoUtils.urls['vimeo_player_unlisted_video'])[1])
#dailymotion
self.assertEqual('dailymotion', tools.get_video_source_data(TestVideoUtils.urls['dailymotion'])[0])
self.assertEqual('x7svr6t', tools.get_video_source_data(TestVideoUtils.urls['dailymotion'])[1])
@@ -72,7 +84,25 @@ class TestVideoUtils(common.BaseCase):
#youtube
self.assertEqual('youtube', tools.get_video_url_data(TestVideoUtils.urls['youtube'])['platform'])
#vimeo
self.assertEqual('vimeo', tools.get_video_url_data(TestVideoUtils.urls['vimeo'])['platform'])
for key in ['vimeo', 'vimeo_player']:
self.assertEqual(tools.get_video_url_data(TestVideoUtils.urls[key]), {
'platform': 'vimeo',
'embed_url': '//player.vimeo.com/video/395399735?autoplay=0',
'video_id': '395399735',
'params': {
'autoplay': 0
}
})
for key in ['vimeo_unlisted_video', 'vimeo_player_unlisted_video']:
self.assertEqual(tools.get_video_url_data(TestVideoUtils.urls[key]), {
'platform': 'vimeo',
'embed_url': '//player.vimeo.com/video/795669787?autoplay=0&h=0763fdb816',
'video_id': '795669787',
'params': {
'autoplay': 0,
'h': '0763fdb816'
}
})
#dailymotion
self.assertEqual('dailymotion', tools.get_video_url_data(TestVideoUtils.urls['dailymotion'])['platform'])
#youku
@@ -90,7 +120,8 @@ class TestVideoUtilsExternal(common.BaseCase):
#youtube
self.assertIsInstance(tools.get_video_thumbnail(TestVideoUtils.urls['youtube']), bytes)
#vimeo
self.assertIsInstance(tools.get_video_thumbnail(TestVideoUtils.urls['vimeo']), bytes)
for key in ['vimeo', 'vimeo_unlisted_video', 'vimeo_player', 'vimeo_player_unlisted_video']:
self.assertIsInstance(tools.get_video_thumbnail(TestVideoUtils.urls[key]), bytes)
#dailymotion
self.assertIsInstance(tools.get_video_thumbnail(TestVideoUtils.urls['dailymotion']), bytes)
#instagram
+14 -3
View File
@@ -8,6 +8,7 @@ import re
import requests
from markupsafe import Markup
from urllib.parse import parse_qs
from werkzeug.urls import url_encode
from odoo import _
@@ -23,7 +24,8 @@ valid_url_regex = r'^(http://|https://|//)[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{
# Regex for few of the widely used video hosting services
player_regexes = {
'youtube': r'^(?:(?:https?:)?//)?(?:www\.)?(?:youtu\.be/|youtube(-nocookie)?\.com/(?:embed/|v/|watch\?v=|watch\?.+&v=))((?:\w|-){11})\S*$',
'vimeo': r'//(player.)?vimeo.com/([a-z]*/)*([0-9]{6,11})[?]?.*',
'vimeo': r'^(?:(?:https?:)?//)?(?:www\.)?vimeo\.com\/(?P<id>[^/\?]+)(?:/(?P<hash>[^/\?]+))?(?:\?(?P<params>[^\s]+))?$',
'vimeo_player': r'^(?:(?:https?:)?//)?player\.vimeo\.com\/video\/(?P<id>[^/\?]+)(?:\?(?P<params>[^\s]+))?$',
'dailymotion': r'(https?:\/\/)(www\.)?(dailymotion\.com\/(embed\/video\/|embed\/|video\/|hub\/.*#video=)|dai\.ly\/)(?P<id>[A-Za-z0-9]{6,7})',
'instagram': r'(?:(.*)instagram.com|instagr\.am)/p/(.[a-zA-Z0-9-_\.]*)',
'youku': r'(?:(https?:\/\/)?(v\.youku\.com/v_show/id_|player\.youku\.com/player\.php/sid/|player\.youku\.com/embed/|cloud\.youku\.com/services/sharev\?vid=|video\.tudou\.com/v/)|youku:)(?P<id>[A-Za-z0-9]+)(?:\.html|/v\.swf|)',
@@ -41,9 +43,11 @@ def get_video_source_data(video_url):
youtube_match = re.search(player_regexes['youtube'], video_url)
if youtube_match:
return ('youtube', youtube_match[2], youtube_match)
vimeo_match = re.search(player_regexes['vimeo'], video_url)
vimeo_match = (
re.search(player_regexes['vimeo'], video_url) or
re.search(player_regexes['vimeo_player'], video_url))
if vimeo_match:
return ('vimeo', vimeo_match[3], vimeo_match)
return ('vimeo', vimeo_match.group('id'), vimeo_match)
dailymotion_match = re.search(player_regexes['dailymotion'], video_url)
if dailymotion_match:
return ('dailymotion', dailymotion_match.group("id"), dailymotion_match)
@@ -100,6 +104,13 @@ def get_video_url_data(video_url, autoplay=False, loop=False, hide_controls=Fals
params['controls'] = 0
if loop:
params['loop'] = 1
groups = platform_match.groupdict()
if groups.get('hash'):
params['h'] = groups['hash']
elif groups.get('params'):
url_params = parse_qs(groups['params'])
if 'h' in url_params:
params['h'] = url_params['h'][0]
embed_url = f'//player.vimeo.com/video/{video_id}'
elif platform == 'dailymotion':
params['autoplay'] = autoplay and 1 or 0