summaryrefslogtreecommitdiff
path: root/addons/website_slides/controllers/main.py
diff options
context:
space:
mode:
authorThibault Delavallée <tde@odoo.com>2019-02-28 15:54:15 +0000
committerThibault Delavallée <tde@odoo.com>2019-03-04 16:28:27 +0000
commitdc76c99a1e6508f24ea059f08fa48975cbfcaff5 (patch)
treec9dd7e5bb46eb488d6d832c887b3a818b3052dd0 /addons/website_slides/controllers/main.py
parenta488cf67ed5ddb3f67e545176039cc12ac6ed7c2 (diff)
[FIX] website_slides: fix display of lessons in training course
Currently slides are displayed in a reorderable list, using current user access rights. This means external customers see only published and free lessons. However purpose of course page is to display all lessons, and display only available ones as clickable. Other one should be displayed as muted to tease people. Note that a specific lesson page does check for access rights. Here we just display all lessons names. A label for free preview is also added. Fetch of data when displaying a channel is therefore a bit modified as there are less differences between training and documentation channels. User progress is also updated to be easier to use in templates. Commit linked to task ID 1941250 and PR #31453
Diffstat (limited to 'addons/website_slides/controllers/main.py')
-rw-r--r--addons/website_slides/controllers/main.py125
1 files changed, 81 insertions, 44 deletions
diff --git a/addons/website_slides/controllers/main.py b/addons/website_slides/controllers/main.py
index 8d3c696c540..dc87a24dafd 100644
--- a/addons/website_slides/controllers/main.py
+++ b/addons/website_slides/controllers/main.py
@@ -19,8 +19,9 @@ _logger = logging.getLogger(__name__)
class WebsiteSlides(WebsiteProfile):
- _slides_per_page = 12
- _slides_per_list = 20
+ SLIDES_PER_PAGE = 12
+ SLIDES_PER_ASIDE = 20
+ SLIDES_PER_CATEGORY = 4
_channel_order_by_criterion = {
'vote': 'total_votes desc',
'view': 'total_views desc',
@@ -64,8 +65,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_ASIDE)
+ related_slides = slide._get_related_slides(self.SLIDES_PER_ASIDE)
values = {
'slide': slide,
'most_viewed_slides': most_viewed_slides,
@@ -90,12 +91,41 @@ class WebsiteSlides(WebsiteProfile):
possible_points = [slide.quiz_first_attempt_reward,slide.quiz_second_attempt_reward,slide.quiz_third_attempt_reward, slide.quiz_fourth_attempt_reward]
return possible_points[attempt_count] if attempt_count < len(possible_points) else possible_points[-1]
+ # CHANNEL UTILITIES
+ # --------------------------------------------------
+
def _get_user_progress(self, channel):
- user_progress = { slide_partner.slide_id.id: slide_partner for slide_partner in request.env['slide.slide.partner'].sudo().search([('channel_id', '=', channel.id),('partner_id', '=', request.env.user.partner_id.id)])}
+ user_progress = {
+ slide_partner.slide_id.id: slide_partner
+ for slide_partner in request.env['slide.slide.partner'].sudo().search([
+ ('channel_id', '=', channel.id),
+ ('partner_id', '=', request.env.user.partner_id.id)
+ ])
+ }
return {
'user_progress': user_progress
}
+ def _get_channel_progress(self, channel):
+ """ Replacement to user_progress. Both may exist in some transient state. """
+ slides = request.env['slide.slide'].sudo().search([('channel_id', '=', channel.id)])
+ channel_progress = dict((sid, dict()) for sid in slides.ids)
+ if not request.env.user._is_public() and channel.is_member:
+ slide_partners = request.env['slide.slide.partner'].sudo().search([
+ ('channel_id', '=', channel.id),
+ ('partner_id', '=', request.env.user.partner_id.id)
+ ])
+ for slide_partner in slide_partners:
+ channel_progress[slide_partner.slide_id.id].update(slide_partner.read()[0])
+ if slide_partner.slide_id.question_ids:
+ gains = [slide_partner.slide_id.quiz_first_attempt_reward,
+ slide_partner.slide_id.quiz_second_attempt_reward,
+ slide_partner.slide_id.quiz_third_attempt_reward,
+ slide_partner.slide_id.quiz_fourth_attempt_reward]
+ channel_progress[slide_partner.slide_id.id]['quiz_gain'] = gains[slide_partner.quiz_attempts_count] if slide_partner.quiz_attempts_count < len(gains) else gains[-1]
+
+ return channel_progress
+
def _extract_channel_tag_search(self, **post):
tags = request.env['slide.channel.tag']
for key in (_key for _key in post if _key.startswith('channel_tag_group_id_')):
@@ -133,9 +163,6 @@ class WebsiteSlides(WebsiteProfile):
domain = expression.AND([domain, [('partner_ids', '=', request.env.user.partner_id.id)]])
return domain
- def _prepare_channel_values(self, **kwargs):
- return dict(**kwargs)
-
# --------------------------------------------------
# MAIN / SEARCH
# --------------------------------------------------
@@ -245,11 +272,6 @@ class WebsiteSlides(WebsiteProfile):
raise werkzeug.exceptions.NotFound()
domain = [('channel_id', '=', channel.id)]
- if not channel.can_publish:
- domain = expression.AND([
- domain,
- ['&', ('website_published', '=', True), ('channel_id.website_published', '=', True)]
- ])
pager_url = "/slides/%s" % (channel.id)
pager_args = {}
@@ -278,13 +300,16 @@ class WebsiteSlides(WebsiteProfile):
pager_url += "?slide_type=%s" % slide_type
# sorting criterion
- actual_sorting = sorting if sorting and sorting in request.env['slide.slide']._order_by_strategy else channel.promote_strategy
+ if channel.channel_type == 'documentation':
+ actual_sorting = sorting if sorting and sorting in request.env['slide.slide']._order_by_strategy else channel.promote_strategy
+ else:
+ actual_sorting = 'sequence'
order = request.env['slide.slide']._order_by_strategy[actual_sorting]
pager_args['sorting'] = actual_sorting
pager_count = request.env['slide.slide'].sudo().search_count(domain)
pager = request.website.pager(url=pager_url, total=pager_count, page=page,
- step=self._slides_per_page, scope=self._slides_per_page,
+ step=self.SLIDES_PER_PAGE, scope=self.SLIDES_PER_PAGE,
url_args=pager_args)
values = {
@@ -323,24 +348,47 @@ class WebsiteSlides(WebsiteProfile):
'last_rating_value': last_message_data.get('rating_value'),
})
- # Display uncategorized slides
- # fetch slides; done as sudo because we want to display all of them but
- # unreachable ones won't be clickable (+ slide controller will crash anyway)
+ # fetch slides and handle uncategorized slides; done as sudo because we want to display all
+ # of them but unreachable ones won't be clickable (+ slide controller will crash anyway)
+ # documentation mode may display less slides than content by category but overhead of
+ # computation is reasonable
if not category and not uncategorized:
category_data = []
- for category in request.env['slide.slide'].sudo().read_group(domain, ['category_id'], ['category_id']):
- category_id, name = category.get('category_id') or (False, _('Uncategorized'))
- slides_sudo = request.env['slide.slide'].sudo().search(category['__domain'], limit=4, offset=0, order=order)
+ all_categories = request.env['slide.category'].search([('channel_id', '=', channel.id)])
+ all_slides = request.env['slide.slide'].sudo().search(domain, order=order)
+
+ uncategorized_slides = all_slides.filtered(lambda slide: not slide.category_id)
+ displayed_slides = uncategorized_slides
+ if channel.channel_type == 'documentation':
+ displayed_slides = uncategorized_slides[:self.SLIDES_PER_CATEGORY]
+ if channel.channel_type == 'training' or displayed_slides:
+ category_data.append({
+ 'category': False, 'id': False,
+ 'name': _('Uncategorized'), 'slug_name': _('Uncategorized'),
+ 'total_slides': len(uncategorized_slides),
+ 'slides': displayed_slides,
+ })
+ for category in all_categories:
+ category_slides = all_slides.filtered(lambda slide: slide.category_id == category)
+ displayed_slides = category_slides
+ if channel.channel_type == 'documentation':
+ displayed_slides = category_slides[:self.SLIDES_PER_CATEGORY]
+ if not displayed_slides:
+ continue
category_data.append({
- 'id': category_id,
- 'name': name,
- 'slug_name': slug((category_id, name)) if category_id else name,
- 'total_slides': category['category_id_count'],
- 'slides': slides_sudo,
+ 'id': category.id,
+ 'name': category.name,
+ 'slug_name': slug(category),
+ 'total_slides': len(category_slides),
+ 'slides': displayed_slides,
})
elif uncategorized:
- slides_sudo = request.env['slide.slide'].sudo().search(domain, limit=self._slides_per_page, offset=pager['offset'], order=order)
+ if channel.channel_type == 'documentation':
+ slides_sudo = request.env['slide.slide'].sudo().search(domain, limit=self.SLIDES_PER_PAGE, offset=pager['offset'], order=order)
+ else:
+ slides_sudo = request.env['slide.slide'].sudo().search(domain, order=order)
category_data = [{
+ 'category': False,
'id': False,
'name': _('Uncategorized'),
'slug_name': _('Uncategorized'),
@@ -348,35 +396,24 @@ class WebsiteSlides(WebsiteProfile):
'slides': slides_sudo,
}]
else:
- slides_sudo = request.env['slide.slide'].sudo().search(domain, limit=self._slides_per_page, offset=pager['offset'], order=order)
+ if channel.channel_type == 'documentation':
+ slides_sudo = request.env['slide.slide'].sudo().search(domain, limit=self.SLIDES_PER_PAGE, offset=pager['offset'], order=order)
+ else:
+ slides_sudo = request.env['slide.slide'].sudo().search(domain, order=order)
category_data = [{
+ 'category': category,
'id': category.id,
'name': category.name,
'slug_name': slug(category),
'total_slides': len(slides_sudo),
'slides': slides_sudo,
}]
-
- # post slide-fetch computation: promoted, user completion (separated because sudo-ed)
- if not request.website.is_public_user() and channel.is_member:
- displayed_slide_ids = list(set(sid for item in category_data for sid in item['slides'].ids))
- done_slide_ids = request.env['slide.slide.partner'].sudo().search([
- ('slide_id', 'in', displayed_slide_ids),
- ('partner_id', '=', request.env.user.partner_id.id),
- ('completed', '=', True)
- ]).mapped('slide_id').ids
- else:
- done_slide_ids = []
- values['done_slide_ids'] = done_slide_ids
values['slide_promoted'] = request.env['slide.slide'].sudo().search(domain, limit=1, order=order)
values['category_data'] = category_data
+ values['channel_progress'] = self._get_channel_progress(channel)
values = self._prepare_additional_channel_values(values, **kw)
- if channel.channel_type == "training":
- values.update(self._get_user_progress(channel))
- values['uncategorized_slides'] = channel.slide_ids.filtered(lambda slide: not slide.category_id)
-
return request.render('website_slides.course_main', values)
@http.route(['/slides/channel/add'], type='http', auth='user', methods=['POST'], website=True)