You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by br...@apache.org on 2018/11/08 21:53:42 UTC

[01/10] allura git commit: [#8253] Add emoji setting info to development.ini

Repository: allura
Updated Branches:
  refs/heads/master e6962608d -> 8f520ef6d


[#8253] Add emoji setting info to development.ini


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8f520ef6
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8f520ef6
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8f520ef6

Branch: refs/heads/master
Commit: 8f520ef6d900e4c0ef08134baa8d8daaebd8830b
Parents: 461792d
Author: Shalitha Suranga <sh...@gmail.com>
Authored: Thu Nov 8 11:36:17 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/development.ini | 10 ++++++++++
 1 file changed, 10 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8f520ef6/Allura/development.ini
----------------------------------------------------------------------
diff --git a/Allura/development.ini b/Allura/development.ini
index 7d32dbc..8922c30 100644
--- a/Allura/development.ini
+++ b/Allura/development.ini
@@ -619,6 +619,16 @@ userstats.count_lines_of_code = true
 ; to avoid race condition, this needs to be a bit longer than the SOLR commitWithin delay.
 ; forgetracker.bin_invalidate_delay = 5
 
+
+;
+; Settings for comment reactions
+;
+
+; If you want to customize emoji list for reactions, uncomment following ini setting and add emoji codes
+; as you wish. Supported emoji codes can be found at https://pypi.org/project/emoji/
+; reactions.emoji_list = :+1:, :-1:, :smile:, :tada:, :confused:, :heart:
+
+
 ;
 ; Optional settings for profiling with https://pypi.python.org/pypi/keas.profile
 ;


[03/10] allura git commit: [#8253] Adding reaction support for UI

Posted by br...@apache.org.
[#8253] Adding reaction support for UI


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/71818772
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/71818772
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/71818772

Branch: refs/heads/master
Commit: 71818772d3443dffbab3fc6aaf7b523554e84d31
Parents: 919f146
Author: Shalitha <sh...@gmail.com>
Authored: Tue Oct 30 22:06:07 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/nf/allura/css/site_style.css      |  6 +++++
 .../allura/templates/widgets/post_widget.html   | 24 ++++++++++++++++++++
 2 files changed, 30 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/71818772/Allura/allura/nf/allura/css/site_style.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/site_style.css b/Allura/allura/nf/allura/css/site_style.css
index 8d5315e..af187a9 100644
--- a/Allura/allura/nf/allura/css/site_style.css
+++ b/Allura/allura/nf/allura/css/site_style.css
@@ -3810,6 +3810,12 @@ fieldset.preferences legend {
     width: 100%;
 }
 
+.post-reactions-list img.emoji { 
+    width: 16px;
+    margin-left: 4px;
+    cursor: pointer;
+}
+
 .meta_post .bubble .header{
     background-color: #ffffff;
     font-size: 0.7em;

http://git-wip-us.apache.org/repos/asf/allura/blob/71818772/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 81be2e0..496d973 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -55,6 +55,10 @@
             {{lib.user_link(value.author())}} - <i style="color: #777">{{lib.abbr_date(value.timestamp)}}</i>
 
             <div class="tools">
+            {% if not c.user.is_anonymous() %}
+                <a href="#" id="react_{{value.slug.replace('/','_')}}" data-commentlink="{{value.url()}}" class="reaction-button icon btn ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"{%if value.status == 'pending'%} style="display:none"{%endif%}>
+                    <span><i class="fa fa-smile-o" aria-hidden="true"></i></span></a>
+            {% endif %}
             {% if (h.has_access(value.thread, 'post')() and value.status == 'ok') or moderator %}
                 <a class="icon reply_post btn" href="#" style="" title="Reply" role="button"><span class="ui-button-text"><i class="fa fa-reply"></i></span></a>
             {% endif %}
@@ -79,6 +83,26 @@
             {% endif %}
 
             <div{% if h.has_access(value, 'moderate') %} class="active-md" data-markdownlink="{{value.url()}}" {% endif %}>{{g.markdown.cached_convert(value, 'text')|safe}}</div>&nbsp;
+            <div class='reactions' style='user-select: none; cursor: default'>
+              {% if value.react_thumbs_up > 0 %}
+              <span>{{ '\U0001F44D' }}</span> {{ value.react_thumbs_up }}
+              {% endif %}
+              {% if value.react_thumbs_down > 0 %}
+              <span>{{ '\U0001F44E' }}</span> {{ value.react_thumbs_down }}
+              {% endif %}
+              {% if value.react_laugh > 0 %}
+              <span>{{ '\U0001F604' }}</span> {{ value.react_laugh }}
+              {% endif %}
+              {% if value.react_hooray > 0 %}
+              <span>{{ '\U0001F389' }}</span> {{ value.react_hooray }}
+              {% endif %}
+              {% if value.react_confused > 0 %}
+              <span>{{ '\U0001F615' }}</span> {{ value.react_confused }}
+              {% endif %}
+              {% if value.react_heart > 0 %}
+              <span>{{ '\U00002764' }}</span> {{ value.react_heart }}
+              {% endif %}
+            </div>
             {{lib.related_artifacts(value)}}
             {% if value.edit_count %}
                 <br><small>Last edit: {{value.last_edit_by().display_name}} {{h.ago(value.last_edit_date)}}</small>


[10/10] allura git commit: [#8253] Refactor logic and cleanup codes

Posted by br...@apache.org.
[#8253] Refactor logic and cleanup codes


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c54ede38
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c54ede38
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c54ede38

Branch: refs/heads/master
Commit: c54ede38405979855a8cc779a92713942d2994c0
Parents: 8d3b43b
Author: Shalitha Suranga <sh...@gmail.com>
Authored: Mon Nov 5 13:37:19 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/lib/utils.py                      |  9 +++
 Allura/allura/lib/widgets/discuss.py            | 74 ++----------------
 .../lib/widgets/resources/js/reactions.js       | 81 ++++++++++++++++++++
 3 files changed, 95 insertions(+), 69 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c54ede38/Allura/allura/lib/utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index 07fd2a1..7a13f17 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -36,6 +36,7 @@ import tg
 import pylons
 import json
 from formencode import Invalid
+from collections import OrderedDict
 from tg.decorators import before_validate
 from pylons.controllers.util import etag_cache
 from paste.deploy.converters import asbool, asint
@@ -774,3 +775,11 @@ def get_reaction_emoji_list():
     else:
         emo_list = emo_list.split(',')
     return emo_list
+
+
+def get_reactions_json():
+    """ Returns global reactions json """
+    j = OrderedDict()
+    for em in get_reaction_emoji_list():
+        j[em] =  pylons.app_globals.emojize(em)
+    return json.dumps(j)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/c54ede38/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index 9ff25f9..1a38101 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -17,6 +17,7 @@
 
 from formencode import validators as fev
 
+import json
 import ew as ew_core
 import ew.jinja2_ew as ew
 from pylons import app_globals as g
@@ -303,15 +304,6 @@ class Post(HierWidget):
         attach_post=AttachPost(submit_text='Attach'),
         attachment=Attachment())
 
-    def get_reaction_tooltip_content(self):
-        """Construct html content for the reaction tooltip"""
-        html = ''
-        for em in utils.get_reaction_emoji_list():
-            emoji_u = g.emojize(em)
-            html += '<span onclick="reactComment(\'` + btnId +  `\', \'%s\')">` + twemoji.parse(\'%s\') + `</span>' % \
-            (em, emoji_u)
-        return html
-
     def resources(self):
         for r in super(Post, self).resources():
             yield r
@@ -439,66 +431,6 @@ class Post(HierWidget):
             });
         }());
         ''')
-        
-        yield ew.JSScript('''
-        // Reaction support
-        $(function(){
-
-        $('.reaction-button').tooltipster({
-            animation: 'fade',
-            delay: 200,
-            theme: 'tooltipster-default',
-            trigger: 'click',
-            position: 'top',
-            iconCloning: false,
-            maxWidth: 400,
-            contentAsHTML: true,
-            interactive: true
-        });
-
-        $('.reaction-button').each(function() {
-            var btnId = $(this).attr('id');
-            $(this).click(function(e) {
-                e.preventDefault();
-                var tooltiptext = `
-                <div class="post-reactions-list">
-                    %s
-                </div>
-                `;
-                $(this).tooltipster('content', tooltiptext);
-                $(this).tooltipster('show', function() {
-                    twemoji.parse($('.tooltipster-content')[0]);
-                });
-            });
-        });
-
-
-        });
-
-        function reactComment(btnId ,r) {
-        var btn = $('#' + btnId);
-        var reacts_list = btn.closest('.post-content').find('.reactions');
-        $.ajax({
-            type: 'post',
-            url: btn.data('commentlink') + 'post_reaction',
-            data: {
-                'r' : r,
-                '_session_id' : $.cookie('_session_id')
-            },
-            success: function(res) {
-                var react_html = '';
-
-                for (var i in res.counts) {
-                    react_html += '<span>' + res.emoji_unicode[i] + '</span> ' + res.counts[i];
-                }
-                
-                reacts_list.html(react_html);
-                twemoji.parse(reacts_list[0]);
-                btn.tooltipster('hide');
-            }
-        });
-        }
-        ''' % self.get_reaction_tooltip_content() ) 
 
 
 class PostThread(ew_core.Widget):
@@ -580,3 +512,7 @@ class Thread(HierWidget):
             }
         });
         ''')
+        yield ew.JSScript('''
+            var global_reactions = %s;
+        ''' % utils.get_reactions_json())
+        yield ew.JSLink('js/reactions.js')

http://git-wip-us.apache.org/repos/asf/allura/blob/c54ede38/Allura/allura/lib/widgets/resources/js/reactions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/reactions.js b/Allura/allura/lib/widgets/resources/js/reactions.js
new file mode 100644
index 0000000..f8df816
--- /dev/null
+++ b/Allura/allura/lib/widgets/resources/js/reactions.js
@@ -0,0 +1,81 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+ */
+
+// Reaction support
+
+$(function(){
+
+$('.reaction-button').tooltipster({
+    animation: 'fade',
+    delay: 200,
+    theme: 'tooltipster-default',
+    trigger: 'click',
+    position: 'top',
+    iconCloning: false,
+    maxWidth: 400,
+    contentAsHTML: true,
+    interactive: true,
+    functionReady: function(instance, helper) {
+        $(helper).find('.emoji_button').click(function() {
+            reactComment(instance, $(this).data('emoji'));
+        });
+    }
+});
+
+$('.reaction-button').each(function() {
+    var btnId = $(this).attr('id');
+    $(this).click(function(e) {
+        e.preventDefault();
+
+        var emohtml = '';
+        for(var emo in global_reactions) {
+            emohtml += '<span class=\'emoji_button\' data-emoji=\'' + emo + '\'>' + 
+            twemoji.parse(global_reactions[emo]) + '</span>';
+        }
+        var tooltiptext = '<div class="post-reactions-list">' + emohtml + '</div>';
+        $(this).tooltipster('content', tooltiptext);
+        $(this).tooltipster('show');
+    });
+});
+
+
+});
+
+function reactComment(btn ,r) {
+var reacts_list = btn.closest('.post-content').find('.reactions');
+$.ajax({
+    type: 'post',
+    url: btn.data('commentlink') + 'post_reaction',
+    data: {
+        'r' : r,
+        '_session_id' : $.cookie('_session_id')
+    },
+    success: function(res) {
+        var react_html = '';
+
+        for (var i in res.counts) {
+            react_html += '<span>' + res.emoji_unicode[i] + '</span> ' + res.counts[i];
+        }
+        
+        reacts_list.html(react_html);
+        twemoji.parse(reacts_list[0]);
+        btn.tooltipster('hide');
+    }
+});
+}
\ No newline at end of file


[05/10] allura git commit: [#8253] JSON Endpoint for reactions

Posted by br...@apache.org.
[#8253] JSON Endpoint for reactions


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/73490b07
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/73490b07
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/73490b07

Branch: refs/heads/master
Commit: 73490b075af289620f7fd7b94833743f6d1456ec
Parents: 62df9f2
Author: Shalitha <sh...@gmail.com>
Authored: Tue Oct 30 22:04:01 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/73490b07/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 6bdc289..f2ea923 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -370,6 +370,29 @@ class PostController(BaseController):
     def get_markdown(self):
         return self.post.text
 
+    @expose('json:')
+    @without_trailing_slash
+    @require_post()
+    def post_reaction(self, r, **kw):
+        if c.user.is_anonymous():
+            return {
+                'error' : 'no_permission'
+            }
+        status = 'ok'
+        if r in self.post.reaction_list:
+            self.post.post_reaction(r, c.user)
+        else:
+            status = 'error' 
+        return {
+            'status' : status,
+            'react_thumbs_up': self.post.react_thumbs_up,
+            'react_thumbs_down': self.post.react_thumbs_down,
+            'react_laugh': self.post.react_laugh,
+            'react_hooray': self.post.react_hooray,
+            'react_confused': self.post.react_confused,
+            'react_heart': self.post.react_heart
+        }
+
     def error_handler(self, *args, **kwargs):
         redirect(request.referer)
 


[07/10] allura git commit: [#8253] Adding reaction scripts to base

Posted by br...@apache.org.
[#8253] Adding reaction scripts to base


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/919f146a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/919f146a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/919f146a

Branch: refs/heads/master
Commit: 919f146ad42e50ce46292ad46ea3c7f525071b19
Parents: 73490b0
Author: Shalitha <sh...@gmail.com>
Authored: Tue Oct 30 22:05:34 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/public/nf/js/allura-base.js | 69 ++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/919f146a/Allura/allura/public/nf/js/allura-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/allura-base.js b/Allura/allura/public/nf/js/allura-base.js
index b59fbe2..87b414f 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -254,3 +254,72 @@ $(function(){
         });
     });
 });
+
+// Reaction support
+$(function(){
+
+    $('.reaction-button').tooltipster({
+        animation: 'fade',
+        delay: 200,
+        theme: 'tooltipster-default',
+        trigger: 'click',
+        position: 'top',
+        iconCloning: false,
+        maxWidth: 400,
+        contentAsHTML: true,
+        interactive: true
+    });
+
+    $('.reaction-button').each(function() {
+        var btnId = $(this).attr('id');
+        $(this).click(function(e) {
+            e.preventDefault();
+            var tooltiptext = `
+            <div class="post-reactions-list">
+                <span onclick="reactComment('` + btnId  + `', 'thumbs_up')"><img draggable="false" class="emoji" alt="👍" src="https://twemoji.maxcdn.com/2/72x72/1f44d.png"></span>
+                <span onclick="reactComment('` + btnId  + `', 'thumbs_down')"><img draggable="false" class="emoji" alt="👎" src="https://twemoji.maxcdn.com/2/72x72/1f44e.png"></span>
+                <span onclick="reactComment('` + btnId  + `', 'laugh')"><img draggable="false" class="emoji" alt="😃" src="https://twemoji.maxcdn.com/2/72x72/1f603.png"></span>
+                <span onclick="reactComment('` + btnId  + `', 'hooray')"><img draggable="false" class="emoji" alt="🎉" src="https://twemoji.maxcdn.com/2/72x72/1f389.png"></span>
+                <span onclick="reactComment('` + btnId  + `', 'confused')"><img draggable="false" class="emoji" alt="😕" src="https://twemoji.maxcdn.com/2/72x72/1f615.png"></span>
+                <span onclick="reactComment('` + btnId  + `', 'heart')"><img draggable="false" class="emoji" alt="❤" src="https://twemoji.maxcdn.com/2/72x72/2764.png"></span>
+            </div>
+            `;
+            $(this).tooltipster('content', tooltiptext);
+            $(this).tooltipster('show');
+        });
+    });
+
+
+});
+
+function reactComment(btnId ,r) {
+    var btn = $('#' + btnId);
+    var reacts_list = btn.closest('.post-content').find('.reactions');
+    $.ajax({
+        type: 'post',
+        url: btn.data('commentlink') + 'post_reaction',
+        data: {
+            'r' : r,
+            '_session_id' : $.cookie('_session_id')
+        },
+        success: function(res) {
+            var react_html = '';
+            if(res.react_thumbs_up > 0) 
+                react_html += '<span>👍</span> ' + res.react_thumbs_up;
+            if(res.react_thumbs_down > 0) 
+                react_html += '<span>👎</span> ' + res.react_thumbs_down;
+            if(res.react_laugh > 0) 
+                react_html += '<span>😄</span> ' + res.react_laugh;
+            if(res.react_hooray > 0) 
+                react_html += '<span>🎉</span> ' + res.react_hooray;
+            if(res.react_confused > 0) 
+                react_html += '<span>😕</span> ' + res.react_confused;
+            if(res.react_heart > 0) 
+                react_html += '<span>❤</span> ' + res.react_heart;
+            
+            reacts_list.html(react_html);
+            twemoji.parse(reacts_list[0]);
+            btn.tooltipster('hide');
+        }
+    });
+}
\ No newline at end of file


[08/10] allura git commit: [#8253] Refactor codes and customizable emojis for reactions

Posted by br...@apache.org.
[#8253] Refactor codes and customizable emojis for reactions


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/8d3b43b1
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/8d3b43b1
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/8d3b43b1

Branch: refs/heads/master
Commit: 8d3b43b10497c02e31d7fe67c95a508421860644
Parents: de72730
Author: Shalitha <sh...@gmail.com>
Authored: Thu Nov 1 15:18:50 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py            | 16 ++---
 Allura/allura/lib/app_globals.py                |  5 ++
 Allura/allura/lib/utils.py                      | 12 ++++
 Allura/allura/lib/widgets/discuss.py            | 72 ++++++++++++++++++++
 Allura/allura/model/artifact.py                 | 57 +++++++---------
 Allura/allura/public/nf/js/allura-base.js       | 69 -------------------
 .../allura/templates/widgets/post_widget.html   | 21 +-----
 Allura/allura/tests/functional/test_discuss.py  | 32 +++++----
 8 files changed, 140 insertions(+), 144 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index f2ea923..1e5e30a 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -379,19 +379,15 @@ class PostController(BaseController):
                 'error' : 'no_permission'
             }
         status = 'ok'
-        if r in self.post.reaction_list:
+        if r in utils.get_reaction_emoji_list():
             self.post.post_reaction(r, c.user)
         else:
             status = 'error' 
-        return {
-            'status' : status,
-            'react_thumbs_up': self.post.react_thumbs_up,
-            'react_thumbs_down': self.post.react_thumbs_down,
-            'react_laugh': self.post.react_laugh,
-            'react_hooray': self.post.react_hooray,
-            'react_confused': self.post.react_confused,
-            'react_heart': self.post.react_heart
-        }
+        emoji_unicode = {}
+        # Need send back unicode emojis too for rendering :+1: .. etc
+        for em_code in self.post.react_counts:
+            emoji_unicode[em_code] = g.emojize(em_code)
+        return dict(status=status, counts=self.post.react_counts, emoji_unicode=emoji_unicode)
 
     def error_handler(self, *args, **kwargs):
         redirect(request.referer)

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index ddcfa14..02980c1 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -34,6 +34,7 @@ import traceback
 import activitystream
 import pkg_resources
 import markdown
+import emoji
 import pygments
 import pygments.lexers
 import pygments.formatters
@@ -608,6 +609,10 @@ class Globals(object):
             "image_height": logo['image_height']
         }
 
+    def emojize(self, text):
+        """Coverts emoji codes to unicode emojis"""
+        return emoji.emojize(text, use_aliases=True)
+
 
 class Icon(object):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/lib/utils.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/utils.py b/Allura/allura/lib/utils.py
index ccc19d2..07fd2a1 100644
--- a/Allura/allura/lib/utils.py
+++ b/Allura/allura/lib/utils.py
@@ -30,6 +30,7 @@ import magic
 from itertools import groupby
 import operator as op
 import collections
+import emoji
 
 import tg
 import pylons
@@ -762,3 +763,14 @@ def umask(new_mask):
         yield
     finally:
         os.umask(cur_mask)
+
+
+def get_reaction_emoji_list():
+    """ Get reactions emoji list from .ini file. If not defined there get fixed 
+    default emoji list """
+    emo_list = tg.config.get('reactions.emoji_list')
+    if emo_list is None:
+        emo_list = [':+1:', ':-1:', ':smile:', ':tada:', ':confused:', ':heart:']
+    else:
+        emo_list = emo_list.split(',')
+    return emo_list

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/lib/widgets/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/discuss.py b/Allura/allura/lib/widgets/discuss.py
index f7be446..9ff25f9 100644
--- a/Allura/allura/lib/widgets/discuss.py
+++ b/Allura/allura/lib/widgets/discuss.py
@@ -19,7 +19,10 @@ from formencode import validators as fev
 
 import ew as ew_core
 import ew.jinja2_ew as ew
+from pylons import app_globals as g
+from  tg import config
 
+from allura.lib import utils
 from allura.lib import validators as V
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets import forms as ff
@@ -300,6 +303,15 @@ class Post(HierWidget):
         attach_post=AttachPost(submit_text='Attach'),
         attachment=Attachment())
 
+    def get_reaction_tooltip_content(self):
+        """Construct html content for the reaction tooltip"""
+        html = ''
+        for em in utils.get_reaction_emoji_list():
+            emoji_u = g.emojize(em)
+            html += '<span onclick="reactComment(\'` + btnId +  `\', \'%s\')">` + twemoji.parse(\'%s\') + `</span>' % \
+            (em, emoji_u)
+        return html
+
     def resources(self):
         for r in super(Post, self).resources():
             yield r
@@ -427,6 +439,66 @@ class Post(HierWidget):
             });
         }());
         ''')
+        
+        yield ew.JSScript('''
+        // Reaction support
+        $(function(){
+
+        $('.reaction-button').tooltipster({
+            animation: 'fade',
+            delay: 200,
+            theme: 'tooltipster-default',
+            trigger: 'click',
+            position: 'top',
+            iconCloning: false,
+            maxWidth: 400,
+            contentAsHTML: true,
+            interactive: true
+        });
+
+        $('.reaction-button').each(function() {
+            var btnId = $(this).attr('id');
+            $(this).click(function(e) {
+                e.preventDefault();
+                var tooltiptext = `
+                <div class="post-reactions-list">
+                    %s
+                </div>
+                `;
+                $(this).tooltipster('content', tooltiptext);
+                $(this).tooltipster('show', function() {
+                    twemoji.parse($('.tooltipster-content')[0]);
+                });
+            });
+        });
+
+
+        });
+
+        function reactComment(btnId ,r) {
+        var btn = $('#' + btnId);
+        var reacts_list = btn.closest('.post-content').find('.reactions');
+        $.ajax({
+            type: 'post',
+            url: btn.data('commentlink') + 'post_reaction',
+            data: {
+                'r' : r,
+                '_session_id' : $.cookie('_session_id')
+            },
+            success: function(res) {
+                var react_html = '';
+
+                for (var i in res.counts) {
+                    react_html += '<span>' + res.emoji_unicode[i] + '</span> ' + res.counts[i];
+                }
+                
+                reacts_list.html(react_html);
+                twemoji.parse(reacts_list[0]);
+                btn.tooltipster('hide');
+            }
+        });
+        }
+        ''' % self.get_reaction_tooltip_content() ) 
 
 
 class PostThread(ew_core.Widget):

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 21aad0d..74480f5 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -1055,22 +1055,11 @@ class ReactableArtifact(MappedClass):
 
     """Reaction support for the Artifact. Use as a mixin."""
 
-    class __mongometa__:
-        session = main_orm_session
-        name = 'reaction'
-
-    react_thumbs_up = FieldProperty(int, if_missing=0)
-    react_thumbs_down = FieldProperty(int, if_missing=0)
-    react_laugh = FieldProperty(int, if_missing=0)
-    react_hooray = FieldProperty(int, if_missing=0)
-    react_confused = FieldProperty(int, if_missing=0)
-    react_heart = FieldProperty(int, if_missing=0)
-
+    react_counts = FieldProperty({str: None}, if_missing=dict())
+    # dict to store reaction counts
     react_users = FieldProperty({str: None}, if_missing=dict())
     # dict to store reactions vs usernames
 
-    reaction_list = ['thumbs_up', 'thumbs_down', 'laugh', 'hooray', 'confused', 'heart']
-
     def post_reaction(self, r, user):
         current_reaction = self.user_reacted(user)
         if current_reaction is None:
@@ -1079,11 +1068,13 @@ class ReactableArtifact(MappedClass):
                 self.react_users[r].append(user.username)
             else:
                 self.react_users[r] = [user.username]
-            self.update_react_count(r, 1)
+            self.update_react_count(r)
         elif current_reaction == r:
             # prev=current so remove
             self.react_users[r].remove(user.username)
-            self.update_react_count(r, -1)
+            self.update_react_count(r, add=False)
+            if len(self.react_users[r]) == 0:
+                self.react_users.pop(r)
         else:
             # prev!=currnet so remove prev then append
             self.react_users[current_reaction].remove(user.username)
@@ -1091,29 +1082,27 @@ class ReactableArtifact(MappedClass):
                 self.react_users[r].append(user.username)
             else:
                 self.react_users[r] = [user.username]
-            self.update_react_count(current_reaction, -1)
-            self.update_react_count(r, 1)
+            self.update_react_count(current_reaction, add=False)
+            self.update_react_count(r)
+            if len(self.react_users[current_reaction]) == 0:
+                self.react_users.pop(current_reaction)
 
     def user_reacted(self, user):
-        for i in self.reaction_list:
-            if i in self.react_users:
-                if user.username in self.react_users[i]:
-                    return i
+        for i in self.react_users:
+            if user.username in self.react_users[i]:
+                return i
         return 
     
-    def update_react_count(self, r, i):
-        if r == 'thumbs_up':
-            self.react_thumbs_up += i
-        elif r == 'thumbs_down':
-            self.react_thumbs_down += i
-        elif r == 'laugh':
-            self.react_laugh += i
-        elif r == 'hooray':
-            self.react_hooray += i
-        elif r == 'confused':
-            self.react_confused += i
-        elif r == 'heart':
-            self.react_heart += i
+    def update_react_count(self, r, add=True):
+        i = 1
+        if not add:
+            i = -1
+        if r in self.react_counts:
+            self.react_counts[r] += i
+            if self.react_counts[r] == 0:
+                self.react_counts.pop(r)
+        else:
+            self.react_counts[r] = 1
 
 class MovedArtifact(Artifact):
 

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/public/nf/js/allura-base.js
----------------------------------------------------------------------
diff --git a/Allura/allura/public/nf/js/allura-base.js b/Allura/allura/public/nf/js/allura-base.js
index 87b414f..b59fbe2 100644
--- a/Allura/allura/public/nf/js/allura-base.js
+++ b/Allura/allura/public/nf/js/allura-base.js
@@ -254,72 +254,3 @@ $(function(){
         });
     });
 });
-
-// Reaction support
-$(function(){
-
-    $('.reaction-button').tooltipster({
-        animation: 'fade',
-        delay: 200,
-        theme: 'tooltipster-default',
-        trigger: 'click',
-        position: 'top',
-        iconCloning: false,
-        maxWidth: 400,
-        contentAsHTML: true,
-        interactive: true
-    });
-
-    $('.reaction-button').each(function() {
-        var btnId = $(this).attr('id');
-        $(this).click(function(e) {
-            e.preventDefault();
-            var tooltiptext = `
-            <div class="post-reactions-list">
-                <span onclick="reactComment('` + btnId  + `', 'thumbs_up')"><img draggable="false" class="emoji" alt="👍" src="https://twemoji.maxcdn.com/2/72x72/1f44d.png"></span>
-                <span onclick="reactComment('` + btnId  + `', 'thumbs_down')"><img draggable="false" class="emoji" alt="👎" src="https://twemoji.maxcdn.com/2/72x72/1f44e.png"></span>
-                <span onclick="reactComment('` + btnId  + `', 'laugh')"><img draggable="false" class="emoji" alt="😃" src="https://twemoji.maxcdn.com/2/72x72/1f603.png"></span>
-                <span onclick="reactComment('` + btnId  + `', 'hooray')"><img draggable="false" class="emoji" alt="🎉" src="https://twemoji.maxcdn.com/2/72x72/1f389.png"></span>
-                <span onclick="reactComment('` + btnId  + `', 'confused')"><img draggable="false" class="emoji" alt="😕" src="https://twemoji.maxcdn.com/2/72x72/1f615.png"></span>
-                <span onclick="reactComment('` + btnId  + `', 'heart')"><img draggable="false" class="emoji" alt="❤" src="https://twemoji.maxcdn.com/2/72x72/2764.png"></span>
-            </div>
-            `;
-            $(this).tooltipster('content', tooltiptext);
-            $(this).tooltipster('show');
-        });
-    });
-
-
-});
-
-function reactComment(btnId ,r) {
-    var btn = $('#' + btnId);
-    var reacts_list = btn.closest('.post-content').find('.reactions');
-    $.ajax({
-        type: 'post',
-        url: btn.data('commentlink') + 'post_reaction',
-        data: {
-            'r' : r,
-            '_session_id' : $.cookie('_session_id')
-        },
-        success: function(res) {
-            var react_html = '';
-            if(res.react_thumbs_up > 0) 
-                react_html += '<span>👍</span> ' + res.react_thumbs_up;
-            if(res.react_thumbs_down > 0) 
-                react_html += '<span>👎</span> ' + res.react_thumbs_down;
-            if(res.react_laugh > 0) 
-                react_html += '<span>😄</span> ' + res.react_laugh;
-            if(res.react_hooray > 0) 
-                react_html += '<span>🎉</span> ' + res.react_hooray;
-            if(res.react_confused > 0) 
-                react_html += '<span>😕</span> ' + res.react_confused;
-            if(res.react_heart > 0) 
-                react_html += '<span>❤</span> ' + res.react_heart;
-            
-            reacts_list.html(react_html);
-            twemoji.parse(reacts_list[0]);
-            btn.tooltipster('hide');
-        }
-    });
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/templates/widgets/post_widget.html
----------------------------------------------------------------------
diff --git a/Allura/allura/templates/widgets/post_widget.html b/Allura/allura/templates/widgets/post_widget.html
index 496d973..fc3f555 100644
--- a/Allura/allura/templates/widgets/post_widget.html
+++ b/Allura/allura/templates/widgets/post_widget.html
@@ -84,24 +84,9 @@
 
             <div{% if h.has_access(value, 'moderate') %} class="active-md" data-markdownlink="{{value.url()}}" {% endif %}>{{g.markdown.cached_convert(value, 'text')|safe}}</div>&nbsp;
             <div class='reactions' style='user-select: none; cursor: default'>
-              {% if value.react_thumbs_up > 0 %}
-              <span>{{ '\U0001F44D' }}</span> {{ value.react_thumbs_up }}
-              {% endif %}
-              {% if value.react_thumbs_down > 0 %}
-              <span>{{ '\U0001F44E' }}</span> {{ value.react_thumbs_down }}
-              {% endif %}
-              {% if value.react_laugh > 0 %}
-              <span>{{ '\U0001F604' }}</span> {{ value.react_laugh }}
-              {% endif %}
-              {% if value.react_hooray > 0 %}
-              <span>{{ '\U0001F389' }}</span> {{ value.react_hooray }}
-              {% endif %}
-              {% if value.react_confused > 0 %}
-              <span>{{ '\U0001F615' }}</span> {{ value.react_confused }}
-              {% endif %}
-              {% if value.react_heart > 0 %}
-              <span>{{ '\U00002764' }}</span> {{ value.react_heart }}
-              {% endif %}
+              {% for reaction in value.react_counts %}
+                <span>{{ g.emojize(reaction) }}</span> {{ value.react_counts[reaction] }}
+              {% endfor %}
             </div>
             {{lib.related_artifacts(value)}}
             {% if value.edit_count %}

http://git-wip-us.apache.org/repos/asf/allura/blob/8d3b43b1/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 5539710..15ef794 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -224,18 +224,20 @@ class TestDiscuss(TestDiscussBase):
         response = self.app.post(
             react_link,
             params={
-                'r': 'heart'})
-        assert response.json['status'] == 'ok' and response.json['react_heart'] == 1
+                'r': ':+1:'})
+        assert response.json['status'] == 'ok' and response.json['counts'][':+1:'] == 1 and \
+        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         response = self.app.post(
             react_link,
             params={
                 'r': 'invalid'})
-        assert response.json['status'] == 'error' and response.json['react_heart'] == 1
+        assert response.json['status'] == 'error' and response.json['counts'][':+1:'] == 1 and \
+        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         # anon users can't react comments
         response = self.app.post(
             react_link,
             params={
-                'r': 'heart'},
+                'r': ':+1:'},
             extra_environ=dict(username='*anonymous'))
         assert response.json['error'] == 'no_permission'
         # even anon can't send invalid reactions
@@ -254,14 +256,16 @@ class TestDiscuss(TestDiscussBase):
         response = self.app.post(
             react_link,
             params={
-                'r': 'thumbs_down'})
-        assert response.json['status'] == 'ok' and response.json['react_thumbs_down'] == 1
+                'r': ':-1:'})
+        assert response.json['status'] == 'ok' and response.json['counts'][':-1:'] == 1 and \
+        response.json['emoji_unicode'][':-1:'] == u'\U0001F44E'
         response = self.app.post(
             react_link,
             params={
-                'r': 'thumbs_up'})
-        assert response.json['status'] == 'ok' and response.json['react_thumbs_up'] == 1
-        assert response.json['status'] == 'ok' and response.json['react_thumbs_down'] == 0
+                'r': ':+1:'})
+        assert response.json['status'] == 'ok' and response.json['counts'][':+1:'] == 1 and \
+        ':-1:' not in response.json['counts'] and ':-1:' not in response.json['emoji_unicode'] and \
+        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
 
     def test_comment_post_reaction_undo(self):
         r = self._make_post('This is a post')
@@ -271,13 +275,15 @@ class TestDiscuss(TestDiscussBase):
         response = self.app.post(
             react_link,
             params={
-                'r': 'hooray'})
-        assert response.json['status'] == 'ok' and response.json['react_hooray'] == 1
+                'r': ':tada:'})
+        assert response.json['status'] == 'ok' and response.json['counts'][':tada:'] == 1 and \
+        response.json['emoji_unicode'][':tada:'] == u'\U0001F389'
         response = self.app.post(
             react_link,
             params={
-                'r': 'hooray'})
-        assert response.json['status'] == 'ok' and response.json['react_hooray'] == 0
+                'r': ':tada:'})
+        assert response.json['status'] == 'ok' and ':tada:' not in response.json['counts'] and \
+        ':tada:' not in response.json['emoji_unicode']
 
     def test_user_filter(self):
         r = self._make_post('Test post')


[04/10] allura git commit: [#8253] Adding Reactable artifact class

Posted by br...@apache.org.
[#8253] Adding Reactable artifact class


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/62df9f20
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/62df9f20
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/62df9f20

Branch: refs/heads/master
Commit: 62df9f2079acc7c802fff662da3f78e86e9fbf3f
Parents: e696260
Author: Shalitha <sh...@gmail.com>
Authored: Tue Oct 30 22:02:04 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/model/artifact.py | 64 ++++++++++++++++++++++++++++++++++++
 Allura/allura/model/discuss.py  |  4 +--
 2 files changed, 66 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/62df9f20/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index 7933e7f..21aad0d 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -1051,6 +1051,70 @@ class VotableArtifact(MappedClass):
         }
 
 
+class ReactableArtifact(MappedClass):
+
+    """Reaction support for the Artifact. Use as a mixin."""
+
+    class __mongometa__:
+        session = main_orm_session
+        name = 'reaction'
+
+    react_thumbs_up = FieldProperty(int, if_missing=0)
+    react_thumbs_down = FieldProperty(int, if_missing=0)
+    react_laugh = FieldProperty(int, if_missing=0)
+    react_hooray = FieldProperty(int, if_missing=0)
+    react_confused = FieldProperty(int, if_missing=0)
+    react_heart = FieldProperty(int, if_missing=0)
+
+    react_users = FieldProperty({str: None}, if_missing=dict())
+    # dict to store reactions vs usernames
+
+    reaction_list = ['thumbs_up', 'thumbs_down', 'laugh', 'hooray', 'confused', 'heart']
+
+    def post_reaction(self, r, user):
+        current_reaction = self.user_reacted(user)
+        if current_reaction is None:
+            # no prev reactions. simply append
+            if r in self.react_users:
+                self.react_users[r].append(user.username)
+            else:
+                self.react_users[r] = [user.username]
+            self.update_react_count(r, 1)
+        elif current_reaction == r:
+            # prev=current so remove
+            self.react_users[r].remove(user.username)
+            self.update_react_count(r, -1)
+        else:
+            # prev!=currnet so remove prev then append
+            self.react_users[current_reaction].remove(user.username)
+            if r in self.react_users:
+                self.react_users[r].append(user.username)
+            else:
+                self.react_users[r] = [user.username]
+            self.update_react_count(current_reaction, -1)
+            self.update_react_count(r, 1)
+
+    def user_reacted(self, user):
+        for i in self.reaction_list:
+            if i in self.react_users:
+                if user.username in self.react_users[i]:
+                    return i
+        return 
+    
+    def update_react_count(self, r, i):
+        if r == 'thumbs_up':
+            self.react_thumbs_up += i
+        elif r == 'thumbs_down':
+            self.react_thumbs_down += i
+        elif r == 'laugh':
+            self.react_laugh += i
+        elif r == 'hooray':
+            self.react_hooray += i
+        elif r == 'confused':
+            self.react_confused += i
+        elif r == 'heart':
+            self.react_heart += i
+
 class MovedArtifact(Artifact):
 
     class __mongometa__:

http://git-wip-us.apache.org/repos/asf/allura/blob/62df9f20/Allura/allura/model/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index d6dc8d7..c7fcc27 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -36,7 +36,7 @@ from allura.lib import security
 from allura.lib.security import require_access, has_access
 from allura.lib import utils
 from allura.model.notification import Notification, Mailbox
-from .artifact import Artifact, ArtifactReference, VersionedArtifact, Snapshot, Message, Feed
+from .artifact import Artifact, ArtifactReference, VersionedArtifact, Snapshot, Message, Feed, ReactableArtifact
 from .attachments import BaseAttachment
 from .auth import User, ProjectRole, AlluraUserProperty
 from .timeline import ActivityObject
@@ -489,7 +489,7 @@ class PostHistory(Snapshot):
         return result
 
 
-class Post(Message, VersionedArtifact, ActivityObject):
+class Post(Message, VersionedArtifact, ActivityObject, ReactableArtifact):
 
     class __mongometa__:
         name = 'post'


[06/10] allura git commit: [#8253] Add unit cases for reaction endpoint

Posted by br...@apache.org.
[#8253] Add unit cases for reaction endpoint


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/de72730c
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/de72730c
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/de72730c

Branch: refs/heads/master
Commit: de72730c21558c1c4d75a244cbe296391b766cd4
Parents: 7181877
Author: Shalitha Suranga <sh...@gmail.com>
Authored: Wed Oct 31 14:25:04 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_discuss.py | 63 +++++++++++++++++++++
 1 file changed, 63 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/de72730c/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 74a490c..5539710 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -216,6 +216,69 @@ class TestDiscuss(TestDiscussBase):
             extra_environ=dict(username='*anonymous'))
         assert response.json['status'] == 'no_permission'
 
+    def test_comment_post_reaction_new(self):
+        r = self._make_post('This is a post')
+        post_id = str(
+            r.html.find('div', {'class': 'discussion-post'})['id'])
+        react_link = str(self._thread_link() + post_id + '/post_reaction')
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'heart'})
+        assert response.json['status'] == 'ok' and response.json['react_heart'] == 1
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'invalid'})
+        assert response.json['status'] == 'error' and response.json['react_heart'] == 1
+        # anon users can't react comments
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'heart'},
+            extra_environ=dict(username='*anonymous'))
+        assert response.json['error'] == 'no_permission'
+        # even anon can't send invalid reactions
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'invalid'},
+            extra_environ=dict(username='*anonymous'))
+        assert response.json['error'] == 'no_permission'
+
+    def test_comment_post_reaction_change(self):
+        r = self._make_post('This is a post')
+        post_id = str(
+            r.html.find('div', {'class': 'discussion-post'})['id'])
+        react_link = str(self._thread_link() + post_id + '/post_reaction')
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'thumbs_down'})
+        assert response.json['status'] == 'ok' and response.json['react_thumbs_down'] == 1
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'thumbs_up'})
+        assert response.json['status'] == 'ok' and response.json['react_thumbs_up'] == 1
+        assert response.json['status'] == 'ok' and response.json['react_thumbs_down'] == 0
+
+    def test_comment_post_reaction_undo(self):
+        r = self._make_post('This is a post')
+        post_id = str(
+            r.html.find('div', {'class': 'discussion-post'})['id'])
+        react_link = str(self._thread_link() + post_id + '/post_reaction')
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'hooray'})
+        assert response.json['status'] == 'ok' and response.json['react_hooray'] == 1
+        response = self.app.post(
+            react_link,
+            params={
+                'r': 'hooray'})
+        assert response.json['status'] == 'ok' and response.json['react_hooray'] == 0
+
     def test_user_filter(self):
         r = self._make_post('Test post')
         post_link = str(


[02/10] allura git commit: [#8253] Chunk assertions to lines

Posted by br...@apache.org.
[#8253] Chunk assertions to lines


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/2593a22b
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/2593a22b
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/2593a22b

Branch: refs/heads/master
Commit: 2593a22b6f0e0e38aba53dd36cd5a09e87e812d0
Parents: c54ede3
Author: Shalitha Suranga <sh...@gmail.com>
Authored: Mon Nov 5 13:37:54 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/tests/functional/test_discuss.py | 33 +++++++++++++--------
 1 file changed, 20 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/2593a22b/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index 15ef794..fbe631b 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -225,14 +225,16 @@ class TestDiscuss(TestDiscussBase):
             react_link,
             params={
                 'r': ':+1:'})
-        assert response.json['status'] == 'ok' and response.json['counts'][':+1:'] == 1 and \
-        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
+        assert response.json['status'] == 'ok'
+        assert response.json['counts'][':+1:'] == 1
+        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         response = self.app.post(
             react_link,
             params={
                 'r': 'invalid'})
-        assert response.json['status'] == 'error' and response.json['counts'][':+1:'] == 1 and \
-        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
+        assert response.json['status'] == 'error' 
+        assert response.json['counts'][':+1:'] == 1
+        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         # anon users can't react comments
         response = self.app.post(
             react_link,
@@ -257,15 +259,18 @@ class TestDiscuss(TestDiscussBase):
             react_link,
             params={
                 'r': ':-1:'})
-        assert response.json['status'] == 'ok' and response.json['counts'][':-1:'] == 1 and \
-        response.json['emoji_unicode'][':-1:'] == u'\U0001F44E'
+        assert response.json['status'] == 'ok'
+        assert response.json['counts'][':-1:'] == 1
+        assert response.json['emoji_unicode'][':-1:'] == u'\U0001F44E'
         response = self.app.post(
             react_link,
             params={
                 'r': ':+1:'})
-        assert response.json['status'] == 'ok' and response.json['counts'][':+1:'] == 1 and \
-        ':-1:' not in response.json['counts'] and ':-1:' not in response.json['emoji_unicode'] and \
-        response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
+        assert response.json['status'] == 'ok'
+        assert response.json['counts'][':+1:'] == 1
+        assert ':-1:' not in response.json['counts']
+        assert ':-1:' not in response.json['emoji_unicode']
+        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
 
     def test_comment_post_reaction_undo(self):
         r = self._make_post('This is a post')
@@ -276,14 +281,16 @@ class TestDiscuss(TestDiscussBase):
             react_link,
             params={
                 'r': ':tada:'})
-        assert response.json['status'] == 'ok' and response.json['counts'][':tada:'] == 1 and \
-        response.json['emoji_unicode'][':tada:'] == u'\U0001F389'
+        assert response.json['status'] == 'ok'
+        assert response.json['counts'][':tada:'] == 1
+        assert response.json['emoji_unicode'][':tada:'] == u'\U0001F389'
         response = self.app.post(
             react_link,
             params={
                 'r': ':tada:'})
-        assert response.json['status'] == 'ok' and ':tada:' not in response.json['counts'] and \
-        ':tada:' not in response.json['emoji_unicode']
+        assert response.json['status'] == 'ok'
+        assert ':tada:' not in response.json['counts']
+        assert ':tada:' not in response.json['emoji_unicode']
 
     def test_user_filter(self):
         r = self._make_post('Test post')


[09/10] allura git commit: [#8253] Remove unwanted emoji unicode response

Posted by br...@apache.org.
[#8253] Remove unwanted emoji unicode response


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/461792d7
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/461792d7
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/461792d7

Branch: refs/heads/master
Commit: 461792d781714e087ebcc2a5fbee81443772f54d
Parents: 2593a22
Author: Shalitha Suranga <sh...@gmail.com>
Authored: Thu Nov 8 11:35:20 2018 +0530
Committer: Dave Brondsema <db...@slashdotmedia.com>
Committed: Thu Nov 8 21:53:25 2018 +0000

----------------------------------------------------------------------
 Allura/allura/controllers/discuss.py                | 6 +-----
 Allura/allura/lib/widgets/resources/js/reactions.js | 2 +-
 Allura/allura/tests/functional/test_discuss.py      | 7 -------
 3 files changed, 2 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/461792d7/Allura/allura/controllers/discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/discuss.py b/Allura/allura/controllers/discuss.py
index 1e5e30a..c7f21ed 100644
--- a/Allura/allura/controllers/discuss.py
+++ b/Allura/allura/controllers/discuss.py
@@ -383,11 +383,7 @@ class PostController(BaseController):
             self.post.post_reaction(r, c.user)
         else:
             status = 'error' 
-        emoji_unicode = {}
-        # Need send back unicode emojis too for rendering :+1: .. etc
-        for em_code in self.post.react_counts:
-            emoji_unicode[em_code] = g.emojize(em_code)
-        return dict(status=status, counts=self.post.react_counts, emoji_unicode=emoji_unicode)
+        return dict(status=status, counts=self.post.react_counts)
 
     def error_handler(self, *args, **kwargs):
         redirect(request.referer)

http://git-wip-us.apache.org/repos/asf/allura/blob/461792d7/Allura/allura/lib/widgets/resources/js/reactions.js
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/widgets/resources/js/reactions.js b/Allura/allura/lib/widgets/resources/js/reactions.js
index f8df816..50fb674 100644
--- a/Allura/allura/lib/widgets/resources/js/reactions.js
+++ b/Allura/allura/lib/widgets/resources/js/reactions.js
@@ -70,7 +70,7 @@ $.ajax({
         var react_html = '';
 
         for (var i in res.counts) {
-            react_html += '<span>' + res.emoji_unicode[i] + '</span> ' + res.counts[i];
+            react_html += '<span>' + global_reactions[i] + '</span> ' + res.counts[i];
         }
         
         reacts_list.html(react_html);

http://git-wip-us.apache.org/repos/asf/allura/blob/461792d7/Allura/allura/tests/functional/test_discuss.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/functional/test_discuss.py b/Allura/allura/tests/functional/test_discuss.py
index fbe631b..9910e5c 100644
--- a/Allura/allura/tests/functional/test_discuss.py
+++ b/Allura/allura/tests/functional/test_discuss.py
@@ -227,14 +227,12 @@ class TestDiscuss(TestDiscussBase):
                 'r': ':+1:'})
         assert response.json['status'] == 'ok'
         assert response.json['counts'][':+1:'] == 1
-        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         response = self.app.post(
             react_link,
             params={
                 'r': 'invalid'})
         assert response.json['status'] == 'error' 
         assert response.json['counts'][':+1:'] == 1
-        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
         # anon users can't react comments
         response = self.app.post(
             react_link,
@@ -261,7 +259,6 @@ class TestDiscuss(TestDiscussBase):
                 'r': ':-1:'})
         assert response.json['status'] == 'ok'
         assert response.json['counts'][':-1:'] == 1
-        assert response.json['emoji_unicode'][':-1:'] == u'\U0001F44E'
         response = self.app.post(
             react_link,
             params={
@@ -269,8 +266,6 @@ class TestDiscuss(TestDiscussBase):
         assert response.json['status'] == 'ok'
         assert response.json['counts'][':+1:'] == 1
         assert ':-1:' not in response.json['counts']
-        assert ':-1:' not in response.json['emoji_unicode']
-        assert response.json['emoji_unicode'][':+1:'] == u'\U0001F44D'
 
     def test_comment_post_reaction_undo(self):
         r = self._make_post('This is a post')
@@ -283,14 +278,12 @@ class TestDiscuss(TestDiscussBase):
                 'r': ':tada:'})
         assert response.json['status'] == 'ok'
         assert response.json['counts'][':tada:'] == 1
-        assert response.json['emoji_unicode'][':tada:'] == u'\U0001F389'
         response = self.app.post(
             react_link,
             params={
                 'r': ':tada:'})
         assert response.json['status'] == 'ok'
         assert ':tada:' not in response.json['counts']
-        assert ':tada:' not in response.json['emoji_unicode']
 
     def test_user_filter(self):
         r = self._make_post('Test post')