Skip to content
Permalink
Browse files

imp

  • Loading branch information...
dja-odoo committed Apr 10, 2019
1 parent c679ece commit 7f9aaade910824caae2cf616c161885cc797872b
@@ -1,11 +1,11 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

import re

from odoo import api, fields, models, _
from odoo.exceptions import ValidationError

from odoo.addons.website.tools.embed import get_video_embed_url


class ProductImage(models.Model):
_name = 'product.image'
@@ -20,61 +20,17 @@ class ProductImage(models.Model):

product_tmpl_id = fields.Many2one('product.template', "Product Template", index=True, ondelete='cascade')
product_variant_id = fields.Many2one('product.product', "Product Variant", index=True, ondelete='cascade')
has_video = fields.Boolean('Add Product Video')
video_url = fields.Char('Video URL',
help='URL of a video for showcasing your product.'
'You can provide URL from Youtube, Instagram, Vimeo, Dailymotion or Youku.')
help='URL of a video for showcasing your product.')
embed_code = fields.Char(compute="_compute_embed_code")

@api.depends('video_url')
def _compute_embed_code(self):
''' Computes the valid iframe containing product video to be embedded.
'''

# Detect if we have an embed code rather than an URL
embedRegex = r'(src|href)=["\']?([^"\']+)?'

# Regex for supported video types
ytRegex = r'^(?:(?:https?:)?\/\/)?(?:www\.)?(?:youtu\.be\/|youtube(-nocookie)?\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((?:\w|-){11})(?:\S+)?$'
vimeoRegex = r'\/\/(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*'
dmRegex = r'.+dailymotion.com\/(video|hub|embed)\/([^_]+)[^#]*(#video=([^_&]+))?'
igRegex = r'(.*)instagram.com\/p\/(.[a-zA-Z0-9]*)'
ykuRegex = r'(.*).youku\.com\/(v_show\/id_|embed\/)(.+)'

for image in self:
embed_url = False
if image.video_url:
videoURL = image.video_url
embedMatch = re.search(embedRegex, image.video_url)

if embedMatch:
videoURL = embedMatch.groups()[1]

ytMatch = re.search(ytRegex, videoURL)
vimeoMatch = re.search(vimeoRegex, videoURL)
dmMatch = re.search(dmRegex, videoURL)
igMatch = re.search(igRegex, videoURL)
ykuMatch = re.search(ykuRegex, videoURL)

if ytMatch and len(ytMatch.groups()[1]) == 11:
embed_url = '//www.youtube%s.com/embed/%s?rel=0' % (ytMatch.groups()[0] or '', ytMatch.groups()[1])
elif vimeoMatch:
embed_url = '//player.vimeo.com/video/%s' % (vimeoMatch.groups()[2])
elif dmMatch:
embed_url = '//www.dailymotion.com/embed/video/%s' % (dmMatch.groups()[1])
elif igMatch:
embed_url = '//www.instagram.com/p/%s/embed/' % (igMatch.groups()[1])
elif ykuMatch:
ykuLink = ykuMatch.groups()[2]
if '.html?' in ykuLink:
ykuLink = ykuLink.split('.html?')[0]
embed_url = '//player.youku.com/embed/%s' % (ykuLink)
image.embed_code = embed_url and '<iframe class="embed-responsive-item" src="%s" allowFullScreen="true" frameborder="0"></iframe>' % embed_url or False
else:
image.embed_code = False
image.embed_code = get_video_embed_url(image.video_url)

@api.constrains('video_url')
def _check_valid_video_url(self):
for image in self:
if image.video_url and not image.embed_code:
raise ValidationError(_("Entered video URL is not valid. Kindly enter proper video URL for '%s'.") % image.name)
raise ValidationError(_("Provided URL for '%s' is not valid. Please enter a valid URL.") % image.name)
@@ -0,0 +1,28 @@
odoo.define('website_sale.video_field_preview', function (require) {
"use strict";


var AbstractField = require('web.AbstractField');
var core = require('web.core');
var fieldRegistry = require('web.field_registry');

var QWeb = core.qweb;

/**
* Displays preview of the video showcasing product.
*/
var FieldVideoPreview = AbstractField.extend({
className: 'd-block o_field_video_preview',

_render: function () {
this.$el.html(QWeb.render('productVideo', {
embedCode: this.value,
}));
},
});

fieldRegistry.add('video_preview', FieldVideoPreview);

return FieldVideoPreview;

});
@@ -638,9 +638,8 @@ a.no-decoration {
position: relative;

.o_product_video_thumb {
position: absolute;
top: 28%;
left: 32%;
@include o-position-absolute($top: 50%, $left: 50%);
transform: translate(-50%, -50%);
color: gray('400');
}
&.active {
@@ -49,9 +49,7 @@

> img {
border: 1px solid gray('400');
min-height: 200px;
max-height: 350px; // Fallback for browsers that dosn't support responsive units
max-height: 50vh;
height: 200px;
width: auto;
}

@@ -61,4 +59,14 @@
}
}
}
.o_video_container {
height: 200px;
position: relative;
@include o-we-preview-box($text-muted);
.o_invalid_warning {
width: 90%;
@include o-position-absolute($top: 50%, $left: 50%);
transform: translate(-50%, -50%);
}
}
}
@@ -18,5 +18,10 @@
</t>
</t>
</t>
<t t-name="productVideo">
<div class="embed-responsive embed-responsive-16by9 mt-2" t-if="embedCode">
<t t-raw="embedCode"/>
</div>
</t>

</templates>
@@ -208,14 +208,30 @@
<h2><field name="name" placeholder="Image Name"/></h2>
<!-- Unfortunately for now we can't drag and drop kanban o2m, so we have to let the user input the sequence manually. -->
<label for="sequence" string="Sequence"/><br/>
<field name="sequence"/>
<group>
<field name="has_video"/>
<field name="video_url" attrs="{'required': [('has_video', '=', True)], 'invisible': [('has_video', '=', False)]}"/>
</group>
<field name="sequence"/><br/><br/>
<label for="sequence" string="Video URL"/><br/>
<field name="video_url"/><br/>
</div>
<div class="col-md-6 col-xl-7 text-center o_website_sale_image_modal_container">
<field name="image_original" widget="image"/>
<div class="row" attrs="{'invisible': [('video_url', 'not in', ['', False])]}">
<div class="col">
<field name="image_original" widget="image"/>
</div>
</div>
<div class="row" attrs="{'invisible': [('video_url', 'in', ['', False])]}">
<div class="col-sm-12 col-md-6">
<field name="image_original" widget="image"/>
</div>
<div class="col-sm-12 col-md-6">
<div class="o_video_container p-2">
<span>Video Preview</span>
<field name="embed_code" class="mt-2" widget="video_preview"/>
<h4 class="o_invalid_warning text-muted text-center" attrs="{'invisible': [('embed_code', '!=', False)]}">
Please enter a valid Video URL.
</h4>
</div>
</div>
</div>
</div>
</div>
</form>
@@ -3,6 +3,7 @@
<!-- Layout and common templates -->
<template id="assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_video_field_preview.js"></script>
<script type="text/javascript" src="/website_sale/static/src/js/website_sale_backend.js"></script>
<link rel="stylesheet" type="text/scss" href="/website_sale/static/src/scss/website_sale_dashboard.scss"/>
<link rel="stylesheet" type="text/scss" href="/website_sale/static/src/scss/website_sale_backend.scss"/>
@@ -1686,7 +1687,7 @@
<div class="carousel-inner h-100">
<t t-foreach="product_images" t-as="product_image">
<div t-attf-class="carousel-item h-100#{' active' if product_image_first else ''}">
<div t-if="product_image._name == 'product.image' and product_image.has_video" class="d-flex align-items-center justify-content-center h-100 embed-responsive embed-responsive-16by9">
<div t-if="product_image._name == 'product.image' and product_image.embed_code" class="d-flex align-items-center justify-content-center h-100 embed-responsive embed-responsive-16by9">
<t t-raw="product_image.embed_code"/>
</div>
<div t-else="" t-field="product_image.image" class="d-flex align-items-center justify-content-center h-100" t-options='{"widget": "image", "preview_image": "image", "class": "product_detail_img mh-100", "alt-field": "name", "zoom": product_image.can_image_be_zoomed and "image_original"}'/>
@@ -1706,7 +1707,7 @@
<ol t-if="len(product_images) > 1" class="carousel-indicators d-inline-block position-static mx-auto my-0 p-1 text-left">
<t t-foreach="product_images" t-as="product_image"><li t-attf-class="d-inline-block m-1 align-top {{'active' if product_image_first else ''}}" data-target="#o-carousel-product" t-att-data-slide-to="str(product_image_index)">
<div t-field="product_image.image_small" class="d-flex align-items-center justify-content-center h-100" t-options='{"widget": "image", "alt-field": "name"}'/>
<i t-if="product_image._name == 'product.image' and product_image.has_video" class="fa fa-2x fa-play-circle-o o_product_video_thumb"/>
<i t-if="product_image._name == 'product.image' and product_image.embed_code" class="fa fa-2x fa-play-circle-o o_product_video_thumb"/>
</li></t>
</ol>
</div>

0 comments on commit 7f9aaad

Please sign in to comment.
You can’t perform that action at this time.