Skip to content
Permalink
Browse files

[IMP] website_slides : allow review, comment and vote only if enough …

…karma

To avoid eLearning to be spammed, the comment, review and vote behaviours
are now allowed only if the user has enought karma to do it.

Here is the new behaviour on courses and slides rating / comment / vote
    -If allow_comment is checked on Course :
        - Review (rating) is allowed on Course only if enought karma
        - Comment is allowed on slides within the course
            only if enought karma and course type is 'training'
        - Vote is allowed on slides within the course
            only if enought karma and course type is 'documentation'
    -If allow_comment is not checked on Course :
        - Review (rating) is not allowed on Course
        - Comment is not allowed on slides within the course
        - Vote is not allowed on slides within the course
    - Rating is not allowed on slides within the course anymore

Task ID : 1943788
PR #31321
  • Loading branch information...
dbeguin committed Mar 8, 2019
1 parent 95221d4 commit 9660d60af9db9eab53527909f091c17de12c5d86
@@ -580,7 +580,7 @@ def validate(self):
@api.one
def refuse(self):
if not self.can_moderate:
raise KarmaError('Not enough karma to refuse a post')
raise KarmaError(_('Not enough karma to refuse a post'))

self.moderator_id = self.env.user
return True
@@ -799,7 +799,7 @@ def message_post(self, message_type='notification', **kwargs):

self.ensure_one()
if not self.can_comment:
raise KarmaError('Not enough karma to comment')
raise KarmaError(_('Not enough karma to comment'))
if not kwargs.get('record_name') and self.parent_id:
kwargs['record_name'] = self.parent_id.name
return super(Post, self).message_post(message_type=message_type, **kwargs)
@@ -574,6 +574,10 @@ def slide_like(self, slide_id, upvote):
if (upvote and slide_partners.vote == 1) or (not upvote and slide_partners.vote == -1):
return {'error': 'vote_done'}
slide = request.env['slide.slide'].browse(int(slide_id))
if not slide.channel_id.allow_comment:
return {'error': 'comment_disabled'}
if not slide.can_vote:
return {'error': 'missing_karma'}
if upvote:
slide.action_like()
else:
@@ -6,6 +6,7 @@

from odoo import api, fields, models, tools, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.gamification.models.gamification_karma_rank import KarmaError
from odoo.exceptions import UserError
from odoo.osv import expression

@@ -112,7 +113,7 @@ def _default_access_token(self):
total_time = fields.Float('# Hours', compute='_compute_slides_statistics', digits=(10, 4), store=True)
# configuration
allow_comment = fields.Boolean(
"Allow comment on Content", default=False,
"Allow rating on Course", default=False,
help="If checked it allows members to either:\n"
" * like content and post comments on documentation course;\n"
" * post comment and review on training course;")
@@ -153,7 +154,10 @@ def _default_access_token(self):
karma_gen_slide_vote = fields.Integer(string='Lesson voted', default=1)
karma_gen_channel_rank = fields.Integer(string='Course ranked', default=5)
karma_gen_channel_finish = fields.Integer(string='Course finished', default=10)
# TODO DBE : Add karma based action rules (like in forum)
# Karma based actions
karma_review = fields.Integer(string='Add a review', default=10, help="Karma needed to add a review on the course")
karma_slide_comment = fields.Integer(string='Add a comment', default=3, help="Karma needed to add a comment on a slide of this course")
karma_slide_vote = fields.Integer(string='Edit own posts', default=3, help="Karma needed to like/dislike a slide of this course.")

@api.depends('slide_ids.is_published')
def _compute_slide_last_update(self):
@@ -316,6 +320,9 @@ def message_post(self, parent_id=False, subtype=None, **kwargs):
through the 'Presentation Published' email, it should be considered as a
note as we don't want all channel followers to be notified of this answer. """
self.ensure_one()
if kwargs.get('message_type') == 'comment':
if self.env.user.karma < self.karma_review:
raise KarmaError(_('Not enough karma to review'))
if parent_id:
parent_message = self.env['mail.message'].sudo().browse(parent_id)
if parent_message.subtype_id and parent_message.subtype_id == self.env.ref('website_slides.mt_channel_slide_published'):
@@ -13,6 +13,7 @@

from odoo import api, fields, models, _
from odoo.addons.http_routing.models.ir_http import slug
from odoo.addons.gamification.models.gamification_karma_rank import KarmaError
from odoo.exceptions import Warning, UserError
from odoo.http import request
from odoo.addons.http_routing.models.ir_http import url_for
@@ -155,6 +156,9 @@ def _default_access_token(self):
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)
# Karma Based action
can_comment = fields.Boolean('Can Comment', compute='_compute_karma_rights')
can_vote = fields.Boolean('Can Vote', compute='_compute_karma_rights')

_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.")
@@ -267,6 +271,12 @@ def _compute_can_publish(self):
def _get_can_publish_error_message(self):
return _("Publishing is restricted to the responsible of training courses or members of the publisher group for documentation courses")

@api.multi
def _compute_karma_rights(self):
for slide in self:
slide.can_comment = self.env.user.karma >= slide.channel_id.karma_slide_comment
slide.can_vote = self.env.user.karma >= slide.channel_id.karma_slide_vote

# ---------------------------------------------------------
# ORM Overrides
# ---------------------------------------------------------
@@ -313,6 +323,15 @@ def write(self, values):
# Mail/Rating
# ---------------------------------------------------------

@api.multi
@api.returns('mail.message', lambda value: value.id)
def message_post(self, message_type='notification', **kwargs):
self.ensure_one()
if self.ids and message_type == 'comment': # user comments have a restriction on karma
if not self.can_comment:
raise KarmaError(_('Not enough karma to comment'))
return super(Slide, self).message_post(message_type=message_type, **kwargs)

@api.multi
def get_access_action(self, access_uid=None):
""" Instead of the classic form view, redirect to website if it is published. """
@@ -59,6 +59,10 @@ var SlideLikeWidget = Widget.extend({
self._popoverAlert(self.$el, _.str.sprintf(_t('Please <a href="/web/login?redirect=%s">login</a> to vote this slide'), (document.URL)));
} else if (data.error === 'vote_done') {
self._popoverAlert(self.$el, _t('You have already voted for this slide'));
} else if (data.error === 'comment_disabled') {
self._popoverAlert(self.$el, _t('Votes and comments are disabled for this channel'));
} else if (data.error === 'missing_karma') {
self._popoverAlert(self.$el, _t('You don\'t have enought karma to vote'));
} else {
self._popoverAlert(self.$el, _t('Unknown error'));
}
@@ -93,7 +93,7 @@
<div class="row">
<h3 class="col-12"><span class="font-weight-bold" t-field="channel.name"/></h3>
<div class="col-12" t-field="channel.description"/>
<div class="col-xs-12 col-md-6 mt8">
<div class="col-xs-12 col-md-6 mt8" t-if="channel.allow_comment and request.env.user.karma >= channel.karma_review">
<t t-call="website_rating.rating_stars_static_popup_composer">
<t t-set="rating_avg" t-value="rating_avg"/>
<t t-set="rating_total" t-value="rating_count"/>
@@ -115,7 +115,7 @@
<i class="fa fa-home"/> Course
</a>
</li>
<li class="nav-item">
<li class="nav-item" t-if="channel.allow_comment">
<a class="nav-link" id="review-tab" data-toggle="pill" href="#review" role="tab" aria-controls="review" aria-selected="false">Review</a>
</li>
</ul>
@@ -237,19 +237,21 @@
</t>
</div>

<span class="text-muted font-weight-bold mr-3">Rating</span>
<div class="text-muted border-left pl-3">
<div class="o_wslides_js_slide_like mr-2">
<span class="o_wslides_js_slide_like_up" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
<i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
<span t-esc="slide.likes"/>
</span>
<span class="o_wslides_js_slide_like_down ml-3" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
<i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
<span t-esc="slide.dislikes"/>
</span>
<t t-if="slide.channel_id.allow_comment and slide.channel_id.channel_type == 'documentation'">
<span class="text-muted font-weight-bold mr-3">Rating</span>
<div class="text-muted border-left pl-3">
<div class="o_wslides_js_slide_like mr-2">
<span class="o_wslides_js_slide_like_up" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
<i class="fa fa-thumbs-up fa-1x" role="img" aria-label="Likes" title="Likes"></i>
<span t-esc="slide.likes"/>
</span>
<span class="o_wslides_js_slide_like_down ml-3" tabindex="0" data-toggle="popover" t-att-data-slide-id="slide.id">
<i class="fa fa-thumbs-down fa-1x" role="img" aria-label="Dislikes" title="Dislikes"></i>
<span t-esc="slide.dislikes"/>
</span>
</div>
</div>
</div>
</t>
</div>
</div>
<div class="row mb-5">
@@ -287,8 +289,7 @@
<div role="tabpanel" t-att-class="comments and 'tab-pane fade in show active' or 'tab-pane fade'" id="discuss">
<t t-call="portal.message_thread">
<t t-set="object" t-value="slide"/>
<t t-set="hash" t-value="message_post_hash"/>
<t t-set="pid" t-value="message_post_pid"/>
<t t-set="disable_composer" t-value="not (slide.can_comment and slide.channel_id.allow_comment and slide.channel_id.channel_type == 'training')"/>
<t t-set="display_rating" t-value="False"/>
</t>
</div>

0 comments on commit 9660d60

Please sign in to comment.
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.