diff --git a/addons/website_slides/__init__.py b/addons/website_slides/__init__.py index 7d34c7c054a..88710707227 100644 --- a/addons/website_slides/__init__.py +++ b/addons/website_slides/__init__.py @@ -3,3 +3,4 @@ from . import controllers from . import models +from . import wizard diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py index 32b4f407e67..a5df3cf0cef 100644 --- a/addons/website_slides/__manifest__.py +++ b/addons/website_slides/__manifest__.py @@ -25,16 +25,18 @@ Share and Publish Videos, Presentations and Documents' 'data': [ 'views/assets.xml', 'views/res_config_settings_views.xml', - 'views/website_slides_templates_homepage.xml', - 'views/website_slides_templates.xml', - 'views/website_slides_embed_templates.xml', 'views/slide_slide_views.xml', 'views/slide_channel_partner_views.xml', 'views/slide_channel_views.xml', 'views/slide_channel_tag_views.xml', - 'views/slide_channel_invite_views.xml', 'views/website_slides_menu_views.xml', + 'views/website_slides_templates_homepage.xml', + 'views/website_slides_templates_course.xml', + 'views/website_slides_templates_lesson.xml', + 'views/website_slides_templates_lesson_embed.xml', 'views/website_slides_templates_profile.xml', + 'views/website_slides_templates_utils.xml', + 'wizard/slide_channel_invite_views.xml', 'data/ir_data.xml', 'data/gamification_data.xml', 'data/mail_data.xml', diff --git a/addons/website_slides/controllers/__init__.py b/addons/website_slides/controllers/__init__.py index acf000fd92c..5f151657861 100644 --- a/addons/website_slides/controllers/__init__.py +++ b/addons/website_slides/controllers/__init__.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from . import mail from . import main diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py index 50cea64c078..27fd663cb31 100644 --- a/addons/website_slides/controllers/main.py +++ b/addons/website_slides/controllers/main.py @@ -53,8 +53,8 @@ class WebsiteSlides(WebsiteProfile): return True def _get_slide_detail(self, slide): - most_viewed_slides = slide.get_most_viewed_slides(self._slides_per_list) - related_slides = slide.get_related_slides(self._slides_per_list) + most_viewed_slides = slide._get_most_viewed_slides(self._slides_per_list) + related_slides = slide._get_related_slides(self._slides_per_list) values = { 'slide': slide, 'most_viewed_slides': most_viewed_slides, @@ -119,7 +119,7 @@ class WebsiteSlides(WebsiteProfile): domain = expression.AND([domain, [('tag_ids', 'in', tags.ids)]]) if slide_type and 'nbr_%ss' % slide_type in request.env['slide.channel']: - domain = expression.AND([domain, [('nbr_%ss' % slide_type, '>', 0)]]) + domain = expression.AND([domain, [('nbr_%s' % slide_type, '>', 0)]]) return domain def _prepare_channel_values(self, **kwargs): @@ -521,7 +521,7 @@ class WebsiteSlides(WebsiteProfile): @http.route(['/slides/slide/send_share_email'], type='json', auth='user', website=True) def slide_send_share_email(self, slide_id, email): slide = request.env['slide.slide'].browse(int(slide_id)) - result = slide.send_share_email(email) + result = slide._send_share_email(email) return result # -------------------------------------------------- diff --git a/addons/website_slides/data/slide_channel_demo.xml b/addons/website_slides/data/slide_channel_demo.xml index 61fc7337d4b..b44cf47dd79 100644 --- a/addons/website_slides/data/slide_channel_demo.xml +++ b/addons/website_slides/data/slide_channel_demo.xml @@ -4,14 +4,13 @@ Basics of Gardening training - latest + most_voted - -
Learn the basics of gardening !
+ Learn the basics of gardening !
Requirements @@ -34,8 +33,7 @@ public - -
In this training you will learn how to take care of trees: when to plant, potted trees, ...
+ Learn how to take care of your favorite trees. Learn when to plant, how to manage potted trees, ...
Interesting Facts @@ -60,8 +58,7 @@ public - -
A lot of nice documentation: trees, wood, gardens. After that you will know everything.
+ A lot of nice documentation: trees, wood, gardens. A gold mine for references.
Trees @@ -87,9 +84,8 @@ public - -
Knowing which kind of wood to use depending on your application is important. In this course you -will learn the basics of wood characteristics.
+ Knowing which kind of wood to use depending on your application is important. In this course you +will learn the basics of wood characteristics.
Introduction @@ -107,9 +103,7 @@ will learn the basics of wood characteristics. invite - -
We're also Santa Claus! Belligerent and numerous. I am the man with no name, - Zapp Brannigan!
+ We're also Santa Claus! Belligerent and numerous. I am the man with no name, Zapp Brannigan!
Introduction @@ -129,7 +123,7 @@ will learn the basics of wood characteristics. invite -
All you need to know about furniture creation.
+ All you need to know about furniture creation.
Introduction diff --git a/addons/website_slides/models/__init__.py b/addons/website_slides/models/__init__.py index 2768668e3e4..9a55188c7ae 100644 --- a/addons/website_slides/models/__init__.py +++ b/addons/website_slides/models/__init__.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. from . import gamification_challenge from . import slide_slide from . import slide_question from . import slide_channel from . import slide_channel_tag -from . import slide_channel_invite from . import res_config_settings from . import website from . import res_users diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 766fde193a0..3dfba4e7576 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -6,7 +6,6 @@ import uuid from odoo import api, fields, models, tools, _ from odoo.addons.http_routing.models.ir_http import slug -from odoo.tools.translate import html_translate from odoo.exceptions import UserError from odoo.osv import expression @@ -63,7 +62,10 @@ class Channel(models.Model): """ A channel is a container of slides. """ _name = 'slide.channel' _description = 'Slide Channel' - _inherit = ['mail.thread', 'website.seo.metadata', 'website.published.multi.mixin', 'rating.mixin'] + _inherit = [ + 'mail.thread', 'rating.mixin', + 'image.mixin', + 'website.seo.metadata', 'website.published.multi.mixin'] _order = 'sequence, id' def _default_access_token(self): @@ -72,7 +74,8 @@ class Channel(models.Model): # description name = fields.Char('Name', translate=True, required=True) active = fields.Boolean(default=True) - description = fields.Html('Description', translate=html_translate, sanitize_attributes=False) + description = fields.Text('Short Description', translate=True) + description_html = fields.Html('Description', translate=tools.html_translate, sanitize_attributes=False) channel_type = fields.Selection([ ('documentation', 'Documentation'), ('training', 'Training')], string="Course type", default="documentation", required=True) @@ -82,10 +85,6 @@ class Channel(models.Model): 'slide.channel.tag', 'slide_channel_tag_rel', 'channel_id', 'tag_id', string='Tags', help='Used to categorize and filter displayed channels/courses') category_ids = fields.One2many('slide.category', 'channel_id', string="Categories") - image = fields.Binary("Image", attachment=True) - image_large = fields.Binary("Large image", attachment=True) - image_medium = fields.Binary("Medium image", attachment=True) - image_small = fields.Binary("Small image", attachment=True) # slides: promote, statistics slide_ids = fields.One2many('slide.slide', 'channel_id', string="Slides") slide_last_update = fields.Date('Last Update', compute='_compute_slide_last_update', store=True) @@ -96,12 +95,12 @@ class Channel(models.Model): ('most_viewed', 'Most Viewed')], string="Featuring Policy", default='latest', required=True) access_token = fields.Char("Security Token", copy=False, default=_default_access_token) - nbr_presentations = fields.Integer('Number of Presentations', compute='_compute_slides_statistics', store=True) - nbr_documents = fields.Integer('Number of Documents', compute='_compute_slides_statistics', store=True) - nbr_videos = fields.Integer('Number of Videos', compute='_compute_slides_statistics', store=True) - nbr_infographics = fields.Integer('Number of Infographics', compute='_compute_slides_statistics', store=True) - nbr_webpages = fields.Integer("Number of Webpages", compute='_compute_slides_statistics', store=True) - nbr_quizs = fields.Integer("Number of quizzes", compute="_compute_slides_statistics", store=True) + nbr_presentation = fields.Integer('Number of Presentations', compute='_compute_slides_statistics', store=True) + nbr_document = fields.Integer('Number of Documents', compute='_compute_slides_statistics', store=True) + nbr_video = fields.Integer('Number of Videos', compute='_compute_slides_statistics', store=True) + nbr_infographic = fields.Integer('Number of Infographics', compute='_compute_slides_statistics', store=True) + nbr_webpage = fields.Integer("Number of Webpages", compute='_compute_slides_statistics', store=True) + nbr_quiz = fields.Integer("Number of Quizs", compute='_compute_slides_statistics', store=True) total_slides = fields.Integer('# Slides', compute='_compute_slides_statistics', store=True, oldname='total') total_views = fields.Integer('# Views', compute='_compute_slides_statistics', store=True) total_votes = fields.Integer('# Votes', compute='_compute_slides_statistics', store=True) @@ -126,7 +125,7 @@ class Channel(models.Model): help='Condition to enroll: everyone, on invite, on payment (sale bridge).') enroll_msg = fields.Html( 'Enroll Message', help="Message explaining the enroll process", - default=False, translate=html_translate, sanitize_attributes=False) + default=False, translate=tools.html_translate, sanitize_attributes=False) enroll_group_ids = fields.Many2many('res.groups', string='Auto Enroll Groups', help="Members of those groups are automatically added as members of the channel.") visibility = fields.Selection([ ('public', 'Public'), ('members', 'Members')], @@ -180,7 +179,7 @@ class Channel(models.Model): @api.depends('slide_ids.slide_type', 'slide_ids.is_published', 'slide_ids.completion_time', 'slide_ids.likes', 'slide_ids.dislikes', 'slide_ids.total_views') def _compute_slides_statistics(self): - result = dict((cid, dict(total_slides=0, total_views=0, total_votes=0, total_time=0)) for cid in self.ids) + result = dict((cid, dict(total_views=0, total_votes=0, total_time=0)) for cid in self.ids) read_group_res = self.env['slide.slide'].read_group( [('is_published', '=', True),('channel_id', 'in', self.ids)], ['channel_id', 'slide_type', 'likes', 'dislikes', 'total_views', 'completion_time'], @@ -188,7 +187,6 @@ class Channel(models.Model): lazy=False) for res_group in read_group_res: cid = res_group['channel_id'][0] - result[cid]['total_slides'] += res_group['__count'] result[cid]['total_views'] += res_group.get('total_views', 0) result[cid]['total_votes'] += res_group.get('likes', 0) result[cid]['total_votes'] -= res_group.get('dislikes', 0) @@ -202,16 +200,16 @@ class Channel(models.Model): record.update(result[record.id]) def _compute_slides_statistics_type(self, read_group_res): - """ Can be overridden to compute stats on added slide_types """ - result = dict((cid, dict(nbr_presentations=0, nbr_documents=0, nbr_videos=0, nbr_infographics=0, nbr_webpages=0, nbr_quizs=0)) for cid in self.ids) + """ Compute statistics based on all existing slide types """ + slide_types = self.env['slide.slide']._fields['slide_type'].get_values(self.env) + keys = ['nbr_%s' % slide_type for slide_type in slide_types] + keys.append('total_slides') + result = dict((cid, dict((key, 0) for key in keys)) for cid in self.ids) for res_group in read_group_res: cid = res_group['channel_id'][0] - result[cid]['nbr_presentations'] += res_group.get('slide_type', '') == 'presentation' and res_group['__count'] or 0 - result[cid]['nbr_documents'] += res_group.get('slide_type', '') == 'document' and res_group['__count'] or 0 - result[cid]['nbr_videos'] += res_group.get('slide_type', '') == 'video' and res_group['__count'] or 0 - result[cid]['nbr_infographics'] += res_group.get('slide_type', '') == 'infographic' and res_group['__count'] or 0 - result[cid]['nbr_webpages'] += res_group.get('slide_type', '') == 'webpage' and res_group['__count'] or 0 - result[cid]['nbr_quizs'] += res_group.get('slide_type', '') == 'quiz' and res_group['__count'] or 0 + for slide_type in slide_types: + result[cid]['nbr_%s' % slide_type] += res_group.get('slide_type', '') == slide_type and res_group['__count'] or 0 + result[cid]['total_slides'] += res_group.get('slide_type', '') == slide_type and res_group['__count'] or 0 return result @api.depends('slide_partner_ids') @@ -259,41 +257,6 @@ class Channel(models.Model): if channel.id: # avoid to perform a slug on a not yet saved record in case of an onchange. channel.website_url = '%s/slides/%s' % (base_url, slug(channel)) - @api.multi - def action_redirect_to_members(self): - action = self.env.ref('website_slides.slide_channel_partner_action').read()[0] - action['view_mode'] = 'tree' - action['domain'] = [('channel_id', 'in', self.ids)] - if len(self) == 1: - action['context'] = {'default_channel_id': self.id} - - return action - - @api.multi - def action_channel_invite(self): - self.ensure_one() - - if self.enroll != 'invite': - raise UserError(_("You cannot send invitations for channels that are not set as 'invite'.")) - - template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False) - - local_context = dict( - self.env.context, - default_channel_id=self.id, - default_use_template=bool(template), - default_template_id=template and template.id or False, - notif_layout='mail.mail_notification_light', - ) - return { - 'type': 'ir.actions.act_window', - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'slide.channel.invite', - 'target': 'new', - 'context': local_context, - } - # --------------------------------------------------------- # ORM Overrides # --------------------------------------------------------- @@ -322,9 +285,8 @@ class Channel(models.Model): vals['channel_partner_ids'] = [(0, 0, { 'partner_id': self.env.user.partner_id.id })] - if 'image' in vals: - tools.image_resize_images(vals, return_large=True) channel = super(Channel, self.with_context(mail_create_nosubscribe=True)).create(vals) + if channel.user_id: channel._action_add_members(channel.user_id.partner_id) if 'enroll_group_ids' in vals: @@ -333,8 +295,6 @@ class Channel(models.Model): @api.multi def write(self, vals): - if 'image' in vals: - tools.image_resize_images(vals, return_large=True) res = super(Channel, self).write(vals) if vals.get('user_id'): self._action_add_members(self.env['res.users'].sudo().browse(vals['user_id']).partner_id) @@ -364,6 +324,41 @@ class Channel(models.Model): # Business / Actions # --------------------------------------------------------- + @api.multi + def action_redirect_to_members(self): + action = self.env.ref('website_slides.slide_channel_partner_action').read()[0] + action['view_mode'] = 'tree' + action['domain'] = [('channel_id', 'in', self.ids)] + if len(self) == 1: + action['context'] = {'default_channel_id': self.id} + + return action + + @api.multi + def action_channel_invite(self): + self.ensure_one() + + if self.visibility != 'invite': + raise UserError(_("You cannot send invitations for channels that are not set as 'invite'.")) + + template = self.env.ref('website_slides.mail_template_slide_channel_invite', raise_if_not_found=False) + + local_context = dict( + self.env.context, + default_channel_id=self.id, + default_use_template=bool(template), + default_template_id=template and template.id or False, + notif_layout='mail.mail_notification_light', + ) + return { + 'type': 'ir.actions.act_window', + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'slide.channel.invite', + 'target': 'new', + 'context': local_context, + } + def action_add_member(self, **member_values): """ Adds the logged in user in the channel members. (see '_action_add_members' for more info) @@ -413,11 +408,6 @@ class Channel(models.Model): for channel in self: channel._action_add_members(channel.mapped('enroll_group_ids.users.partner_id')) - def list_all(self): - return { - 'channels': [{'id': channel.id, 'name': channel.name, 'website_url': channel.website_url} for channel in self.search([])] - } - # --------------------------------------------------------- # Rating Mixin API # --------------------------------------------------------- @@ -439,12 +429,12 @@ class Category(models.Model): channel_id = fields.Many2one('slide.channel', string="Channel", required=True, ondelete='cascade') sequence = fields.Integer(default=10, help='Display order') slide_ids = fields.One2many('slide.slide', 'category_id', string="Slides") - nbr_presentations = fields.Integer("Number of Presentations", compute='_count_presentations', store=True) - nbr_documents = fields.Integer("Number of Documents", compute='_count_presentations', store=True) - nbr_videos = fields.Integer("Number of Videos", compute='_count_presentations', store=True) - nbr_infographics = fields.Integer("Number of Infographics", compute='_count_presentations', store=True) - nbr_webpages = fields.Integer("Number of Webpages", compute='_count_presentations', store=True) - nbr_quizs = fields.Integer("Number of quizzes", compute="_count_presentations", store=True) + nbr_presentation = fields.Integer("Number of Presentations", compute='_count_presentations', store=True) + nbr_document = fields.Integer("Number of Documents", compute='_count_presentations', store=True) + nbr_video = fields.Integer("Number of Videos", compute='_count_presentations', store=True) + nbr_infographic = fields.Integer("Number of Infographics", compute='_count_presentations', store=True) + nbr_webpage = fields.Integer("Number of Webpages", compute='_count_presentations', store=True) + nbr_quiz = fields.Integer("Number of Quizs", compute="_count_presentations", store=True) total_slides = fields.Integer(compute='_count_presentations', store=True, oldname='total') @api.depends('slide_ids.slide_type', 'slide_ids.is_published') @@ -454,29 +444,23 @@ class Category(models.Model): [('is_published', '=', True), ('category_id', 'in', self.ids)], ['category_id', 'slide_type'], ['category_id', 'slide_type'], lazy=False) - for res_group in res: - result[res_group['category_id'][0]][res_group['slide_type']] = result[res_group['category_id'][0]].get(res_group['slide_type'], 0) + res_group['__count'] + + type_stats = self._compute_slides_statistics_type(res) + for cid, cdata in type_stats.items(): + result[cid].update(cdata) for record in self: - record.update(self._extract_count_presentations_type(result, record.id)) + record.update(result[record.id]) - def _extract_count_presentations_type(self, result, record_id): - """ Can be overridden to compute stats on added slide_types """ - statistics = { - 'nbr_presentations': result[record_id].get('presentation', 0), - 'nbr_documents': result[record_id].get('document', 0), - 'nbr_videos': result[record_id].get('video', 0), - 'nbr_infographics': result[record_id].get('infographic', 0), - 'nbr_webpages': result[record_id].get('webpage', 0), - 'nbr_quizs': result[record_id].get('quiz', 0), - 'total_slides': 0 - } - - statistics['total_slides'] += statistics['nbr_presentations'] - statistics['total_slides'] += statistics['nbr_documents'] - statistics['total_slides'] += statistics['nbr_videos'] - statistics['total_slides'] += statistics['nbr_infographics'] - statistics['total_slides'] += statistics['nbr_webpages'] - statistics['total_slides'] += statistics['nbr_quizs'] - - return statistics + def _compute_slides_statistics_type(self, read_group_res): + """ Compute statistics based on all existing slide types """ + slide_types = self.env['slide.slide']._fields['slide_type'].get_values(self.env) + keys = ['nbr_%s' % slide_type for slide_type in slide_types] + keys.append('total_slides') + result = dict((cid, dict((key, 0) for key in keys)) for cid in self.ids) + for res_group in read_group_res: + cid = res_group['category_id'][0] + for slide_type in slide_types: + result[cid]['nbr_%s' % slide_type] += res_group.get('slide_type', '') == slide_type and res_group['__count'] or 0 + result[cid]['total_slides'] += res_group.get('slide_type', '') == slide_type and res_group['__count'] or 0 + return result diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py index 0193558ba46..9d497190434 100644 --- a/addons/website_slides/models/slide_question.py +++ b/addons/website_slides/models/slide_question.py @@ -8,14 +8,11 @@ from odoo.exceptions import ValidationError class SlideQuestion(models.Model): _name = "slide.question" _rec_name = "question" - _description = """ - Question for a slide. A slide can have multiple questions and each question - must have at least 2 possible answers and only one good answer. - """ + _description = "Slide Quiz Question" sequence = fields.Integer("Sequence", default=10) - question = fields.Char("Question Name", required=True) - slide_id = fields.Many2one('slide.slide', string="Slide") + question = fields.Char("Question Name", required=True, translate=True) + slide_id = fields.Many2one('slide.slide', string="Slide", required=True) answer_ids = fields.One2many('slide.answer', 'question_id', string="Answer") @api.constrains('answer_ids') @@ -44,8 +41,9 @@ class SlideQuestion(models.Model): class SlideAnswer(models.Model): _name = "slide.answer" _rec_name = "text_value" - _description = """Answer for a slide question""" + _description = "Answer for a slide question" + _order = 'question_id, id' - question_id = fields.Many2one('slide.question', string="Question") - text_value = fields.Char("Answer", required=True,) - is_correct = fields.Boolean("Is correct answer", default=False) + question_id = fields.Many2one('slide.question', string="Question", required=True) + text_value = fields.Char("Answer", required=True, translate=True) + is_correct = fields.Boolean("Is correct answer") diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index fe022f83b31..6c39f8a7cd6 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -11,7 +11,7 @@ import uuid from werkzeug import urls -from odoo import api, fields, models, tools, _ +from odoo import api, fields, models, _ from odoo.addons.http_routing.models.ir_http import slug from odoo.exceptions import Warning, UserError from odoo.http import request @@ -77,19 +77,11 @@ class SlideTag(models.Model): class Slide(models.Model): - """ This model represents actual presentations. Those must be one of four - types: - - - Presentation - - Document - - Infographic - - Video - - Webpage - - Slide has various statistics like view count, embed count, like, dislikes """ - _name = 'slide.slide' - _inherit = ['mail.thread', 'website.seo.metadata', 'website.published.mixin', 'rating.mixin'] + _inherit = [ + 'mail.thread', 'rating.mixin', + 'image.mixin', + 'website.seo.metadata', 'website.published.mixin'] _description = 'Slides' _mail_post_access = 'read' _order_by_strategy = { @@ -99,10 +91,6 @@ class Slide(models.Model): } _order = 'category_sequence asc, sequence asc' - _sql_constraints = [ - ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.") - ] - def _default_access_token(self): return str(uuid.uuid4()) @@ -119,10 +107,6 @@ class Slide(models.Model): access_token = fields.Char("Security Token", copy=False, default=_default_access_token) is_preview = fields.Boolean('Always visible', default=False) completion_time = fields.Float('# Hours', default=1, digits=(10, 4)) - image = fields.Binary("Image", attachment=True) - image_large = fields.Binary("Large image", attachment=True) - image_medium = fields.Binary("Medium image", attachment=True) - image_small = fields.Binary("Small image", attachment=True) # subscribers partner_ids = fields.Many2many('res.partner', 'slide_slide_partner', 'slide_id', 'partner_id', string='Subscribers', groups='base.group_website_publisher') @@ -161,13 +145,17 @@ class Slide(models.Model): likes = fields.Integer('Likes', compute='_compute_user_info', store=True) dislikes = fields.Integer('Dislikes', compute='_compute_user_info', store=True) user_vote = fields.Integer('User vote', compute='_compute_user_info') - embed_code = fields.Text('Embed Code', readonly=True, compute='_get_embed_code') + embed_code = fields.Text('Embed Code', readonly=True, compute='_compute_embed_code') # views embedcount_ids = fields.One2many('slide.embed', 'slide_id', string="Embed Count") slide_views = fields.Integer('# of Website Views', store=True, compute="_compute_slide_views") public_views = fields.Integer('# of Public Views') total_views = fields.Integer("Total # Views", default="0", compute='_compute_total', store=True) + _sql_constraints = [ + ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.") + ] + @api.depends('slide_views', 'public_views') def _compute_total(self): for record in self: @@ -216,7 +204,8 @@ class Slide(models.Model): self.env['slide.slide.partner'] ) - def _get_embed_code(self): + @api.depends('document_id', 'slide_type', 'mime_type') + def _compute_embed_code(self): base_url = request and request.httprequest.url_root or self.env['ir.config_parameter'].sudo().get_param('web.base.url') if base_url[-1] == '/': base_url = base_url[:-1] @@ -235,7 +224,7 @@ class Slide(models.Model): record.embed_code = False @api.onchange('url') - def on_change_url(self): + def _on_change_url(self): self.ensure_one() if self.url: res = self._parse_document_url(self.url) @@ -250,6 +239,7 @@ class Slide(models.Model): @api.multi @api.depends('name') def _compute_website_url(self): + # TDE FIXME: clena this link.tracker strange stuff super(Slide, self)._compute_website_url() base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') for slide in self: @@ -296,9 +286,6 @@ class Slide(models.Model): for key, value in doc_data.items(): values.setdefault(key, value) - if 'image' in values: - tools.image_resize_images(values, return_large=True) - slide = super(Slide, self).create(values) if slide.website_published: @@ -312,15 +299,16 @@ class Slide(models.Model): for key, value in doc_data.items(): values.setdefault(key, value) - if 'image' in values: - tools.image_resize_images(values, return_large=True) - res = super(Slide, self).write(values) if values.get('website_published'): self.date_published = datetime.datetime.now() self._post_publication() return res + # --------------------------------------------------------- + # Mail/Rating + # --------------------------------------------------------- + @api.multi def get_access_action(self, access_uid=None): """ Instead of the classic form view, redirect to website if it is published. """ @@ -335,10 +323,6 @@ class Slide(models.Model): } return super(Slide, self).get_access_action(access_uid) - # --------------------------------------------------------- - # Business Methods - # --------------------------------------------------------- - @api.multi def _notify_get_groups(self, message, groups): """ Add access button to everyone if the document is active. """ @@ -350,7 +334,12 @@ class Slide(models.Model): return groups - def get_related_slides(self, limit=20): + # --------------------------------------------------------- + # Business Methods + # --------------------------------------------------------- + + def _get_related_slides(self, limit=20): + # TDE FIXME: should build a smarter domain domain = request.website.website_domain() domain += [('website_published', '=', True), ('id', '!=', self.id)] if self.category_id: @@ -358,7 +347,8 @@ class Slide(models.Model): for record in self.search(domain, limit=limit): yield record - def get_most_viewed_slides(self, limit=20): + def _get_most_viewed_slides(self, limit=20): + # TDE FIXME: should build a smarter domain domain = request.website.website_domain() domain += [('website_published', '=', True), ('id', '!=', self.id)] for record in self.search(domain, limit=limit, order='total_views desc'): @@ -387,10 +377,13 @@ class Slide(models.Model): self.write({'access_token': self._default_access_token()}) return self._sign_token(partner_id) - @api.one - def send_share_email(self, email): + def _send_share_email(self, email): + # TDE FIXME: template to check + mail_ids = [] base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - return self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(self.id, notif_layout='mail.mail_notification_light') + for record in self: + mail_ids.append(self.channel_id.share_template_id.with_context(email=email, base_url=base_url).send_mail(record.id, notif_layout='mail.mail_notification_light')) + return mail_ids def action_like(self): self.check_access_rights('read') diff --git a/addons/website_slides/static/src/img/banner-default.jpg b/addons/website_slides/static/src/img/banner-default.jpg deleted file mode 100644 index a594ca906e8..00000000000 Binary files a/addons/website_slides/static/src/img/banner-default.jpg and /dev/null differ diff --git a/addons/website_slides/static/src/img/channel-default.jpg b/addons/website_slides/static/src/img/channel-default.jpg deleted file mode 100644 index dce2a23b9b2..00000000000 Binary files a/addons/website_slides/static/src/img/channel-default.jpg and /dev/null differ diff --git a/addons/website_slides/static/src/img/channel_demo_gardening.jpg b/addons/website_slides/static/src/img/channel_demo_gardening.jpg index 3993e10b42b..2446a667733 100644 Binary files a/addons/website_slides/static/src/img/channel_demo_gardening.jpg and b/addons/website_slides/static/src/img/channel_demo_gardening.jpg differ diff --git a/addons/website_slides/static/src/img/channel_demo_gardening_2.jpg b/addons/website_slides/static/src/img/channel_demo_gardening_2.jpg index 701af0f6588..f5899039d13 100644 Binary files a/addons/website_slides/static/src/img/channel_demo_gardening_2.jpg and b/addons/website_slides/static/src/img/channel_demo_gardening_2.jpg differ diff --git a/addons/website_slides/static/src/img/channel_demo_gardening_3.jpg b/addons/website_slides/static/src/img/channel_demo_gardening_3.jpg new file mode 100644 index 00000000000..3993e10b42b Binary files /dev/null and b/addons/website_slides/static/src/img/channel_demo_gardening_3.jpg differ diff --git a/addons/website_slides/tests/test_statistics.py b/addons/website_slides/tests/test_statistics.py index d59590d1cbf..8068c073bf3 100644 --- a/addons/website_slides/tests/test_statistics.py +++ b/addons/website_slides/tests/test_statistics.py @@ -37,10 +37,10 @@ class TestStatistics(common.SlidesCase): channel_publisher = self.channel.sudo(self.user_publisher) # slide type computation self.assertEqual(channel_publisher.total_slides, len(channel_publisher.slide_ids)) - self.assertEqual(channel_publisher.nbr_infographics, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'infographic'))) - self.assertEqual(channel_publisher.nbr_presentations, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'presentation'))) - self.assertEqual(channel_publisher.nbr_documents, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'document'))) - self.assertEqual(channel_publisher.nbr_videos, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'video'))) + self.assertEqual(channel_publisher.nbr_infographic, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'infographic'))) + self.assertEqual(channel_publisher.nbr_presentation, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'presentation'))) + self.assertEqual(channel_publisher.nbr_document, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'document'))) + self.assertEqual(channel_publisher.nbr_video, len(channel_publisher.slide_ids.filtered(lambda s: s.slide_type == 'video'))) # slide statistics computation self.assertEqual(float_compare(channel_publisher.total_time, sum(s.completion_time for s in channel_publisher.slide_ids), 3), 0) # members computation diff --git a/addons/website_slides/views/slide_channel_views.xml b/addons/website_slides/views/slide_channel_views.xml index 74f920a68a7..e85097bdd8b 100644 --- a/addons/website_slides/views/slide_channel_views.xml +++ b/addons/website_slides/views/slide_channel_views.xml @@ -114,10 +114,11 @@ - - - - + + + + + diff --git a/addons/website_slides/views/website_slides_templates_course.xml b/addons/website_slides/views/website_slides_templates_course.xml new file mode 100644 index 00000000000..0ed270e2fbd --- /dev/null +++ b/addons/website_slides/views/website_slides_templates_course.xml @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + diff --git a/addons/website_slides/views/website_slides_templates.xml b/addons/website_slides/views/website_slides_templates_lesson.xml similarity index 57% rename from addons/website_slides/views/website_slides_templates.xml rename to addons/website_slides/views/website_slides_templates_lesson.xml index 7f0bc0d9553..3b3600b6e47 100644 --- a/addons/website_slides/views/website_slides_templates.xml +++ b/addons/website_slides/views/website_slides_templates_lesson.xml @@ -1,454 +1,7 @@ - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + diff --git a/addons/website_slides/views/website_slides_embed_templates.xml b/addons/website_slides/views/website_slides_templates_lesson_embed.xml similarity index 100% rename from addons/website_slides/views/website_slides_embed_templates.xml rename to addons/website_slides/views/website_slides_templates_lesson_embed.xml diff --git a/addons/website_slides/views/website_slides_templates_utils.xml b/addons/website_slides/views/website_slides_templates_utils.xml new file mode 100644 index 00000000000..57d5c2fced5 --- /dev/null +++ b/addons/website_slides/views/website_slides_templates_utils.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + diff --git a/addons/website_slides/wizard/__init__.py b/addons/website_slides/wizard/__init__.py new file mode 100644 index 00000000000..4020988908b --- /dev/null +++ b/addons/website_slides/wizard/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import slide_channel_invite diff --git a/addons/website_slides/models/slide_channel_invite.py b/addons/website_slides/wizard/slide_channel_invite.py similarity index 100% rename from addons/website_slides/models/slide_channel_invite.py rename to addons/website_slides/wizard/slide_channel_invite.py diff --git a/addons/website_slides/views/slide_channel_invite_views.xml b/addons/website_slides/wizard/slide_channel_invite_views.xml similarity index 100% rename from addons/website_slides/views/slide_channel_invite_views.xml rename to addons/website_slides/wizard/slide_channel_invite_views.xml diff --git a/addons/website_slides_survey/models/slide_channel.py b/addons/website_slides_survey/models/slide_channel.py index d4132d33151..75d5d6ad88f 100644 --- a/addons/website_slides_survey/models/slide_channel.py +++ b/addons/website_slides_survey/models/slide_channel.py @@ -7,26 +7,10 @@ from odoo import fields, models class Channel(models.Model): _inherit = 'slide.channel' - nbr_certifications = fields.Integer("Number of Certifications", compute='_compute_slides_statistics', store=True) - - def _compute_slides_statistics_type(self, read_group_res): - result = super(Channel, self)._compute_slides_statistics_type(read_group_res) - for cid in result: - result[cid]['nbr_certifications'] = 0 - for res_group in read_group_res: - cid = res_group['channel_id'][0] - result[cid]['nbr_certifications'] += res_group.get('slide_type', '') == 'certification' and res_group['__count'] or 0 - return result + nbr_certification = fields.Integer("Number of Certifications", compute='_compute_slides_statistics', store=True) class Category(models.Model): _inherit = 'slide.category' - nbr_certifications = fields.Integer("Number of Certifications", compute='_count_presentations', store=True) - - def _extract_count_presentations_type(self, result, record_id): - statistics = super(Category, self)._extract_count_presentations_type(result, record_id) - statistics['nbr_certifications'] = result[record_id].get('certification', 0) - statistics['total_slides'] += statistics['nbr_certifications'] - - return statistics + nbr_certification = fields.Integer("Number of Certifications", compute='_count_presentations', store=True) diff --git a/addons/website_slides_survey/views/slide_channel_views.xml b/addons/website_slides_survey/views/slide_channel_views.xml index 566bef457fa..e28b67997cf 100644 --- a/addons/website_slides_survey/views/slide_channel_views.xml +++ b/addons/website_slides_survey/views/slide_channel_views.xml @@ -6,7 +6,7 @@ - +