Changeset 1201 in products


Ignore:
Timestamp:
Jul 31, 2009 3:30:02 PM (15 years ago)
Author:
liebster
Message:

Added "report abuse" feature contributed by jcbrand.

Location:
quintagroup.plonecomments/trunk
Files:
11 added
8 edited

Legend:

Unmodified
Added
Removed
  • quintagroup.plonecomments/trunk/docs/HISTORY.txt

    r1059 r1201  
    1 ========= 
    21Changelog 
    32========= 
     3 
     4 
     54.0.4 (unreleased) 
     6================== 
     7 
     8- Added "report abuse" feature contributed by jcbrand. 
     9  [liebster] 
     10 
    411 
    5124.0.1 (2009-06-05) 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.pt

    r822 r1201  
    44                   isAnon view/is_anonymous; 
    55                   ifModerate view/is_moderation_enabled; 
    6                    isModerationAllowed view/can_moderate" 
     6                   isModerationAllowed view/can_moderate; 
     7                   isAuthenticatedReportAbuseEnabled view/authenticated_report_abuse_enabled; 
     8                   isAjaxReportAbuseEnabled view/ajax_report_abuse_enabled; 
     9                   isAnonymousReportAbuseEnabled view/anonymous_report_abuse_enabled; 
     10                   isReportAbuseEnabled python:isAnonymousReportAbuseEnabled or not isAnon and isAuthenticatedReportAbuseEnabled" 
    711                   i18n:domain="plone"> 
    812    <div class="discussion" 
     
    3640                tal:define="indent python:reply_dict['depth']*2; 
    3741                            reply python:reply_dict['object']; 
     42                            comment_id python:reply_dict['object'].id; 
    3843                            isPublished python:reply.review_state=='published';" 
    3944                tal:attributes="style string:margin-left:${indent}em;"> 
     
    9095                           /> 
    9196                </form> 
     97                <tal:if tal:condition="python:isReportAbuseEnabled and isPublished"> 
     98                    <form class="report_abuse" 
     99                          name="report_abuse" 
     100                          method="post" 
     101                          style="display: inline;" 
     102                          tal:attributes="action string:${reply/absolute_url}/report_abuse_form#discussion"> 
     103                        <input type="hidden" name="comment_id" tal:attributes="value comment_id" /> 
     104                        <input class="standalone" 
     105                            type="submit" 
     106                            value="Report Abuse" 
     107                            tal:define="onclick string:javascript:render_abuse_report_form(${comment_id})" 
     108                            tal:attributes="onclick python:isAjaxReportAbuseEnabled and onclick or ''; 
     109                                            id string:input-render-abuse-cancel-${comment_id}" 
     110                            i18n:attributes="value label_report_abuse;" 
     111                            /> 
     112                    </form> 
     113                    <span tal:attributes="id string:span-reply-form-holder-${comment_id}" 
     114                            tal:condition="isReportAbuseEnabled"> 
     115                        <metal:macro use-macro="here/report_abuse_form/macros/form"/> 
     116                    </span> 
     117                    <span tal:attributes="id string:span-abuse-count-holder-${comment_id}"></span> 
     118                </tal:if> 
    92119                <form name="publish_discussion" 
    93120                      action="" 
     
    108135                     i18n:domain="quintagroup.plonecomments" 
    109136                     tal:condition="not:isPublished">Comment must be approved before replies to comment accepted.</div> 
    110  
    111137            </div> 
    112138        </tal:getreplies> 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/comments.py

    r822 r1201  
    33from Acquisition import aq_inner 
    44from AccessControl import getSecurityManager 
     5 
     6from Products.CMFPlone.utils import IndexIterator 
    57from Products.CMFPlone.utils import getToolByName 
     8from Products.CMFFormController.ControllerState import ControllerState 
     9from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile 
     10from quintagroup.plonecomments.utils import manage_mails 
    611 
    7 from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile 
    812from plone.app.layout.viewlets import comments 
     13from plone.app.kss.plonekssview import PloneKSSView 
    914 
    1015class CommentsViewlet(comments.CommentsViewlet): 
    1116    """A custom version of the comments viewlet 
    1217    """ 
    13  
    1418    render = ViewPageTemplateFile('comments.pt') 
    1519 
     
    5256 
    5357        return gravatar_url 
     58 
     59    def authenticated_report_abuse_enabled(self): 
     60        """ """ 
     61        portal_properties = getToolByName(self.context, 'portal_properties') 
     62        prop_sheet = portal_properties['qPloneComments'] 
     63        value =  prop_sheet.getProperty('enable_authenticated_report_abuse', False) 
     64        return value 
     65 
     66    def anonymous_report_abuse_enabled(self): 
     67        """ """ 
     68        portal_properties = getToolByName(self.context, 'portal_properties') 
     69        prop_sheet = portal_properties['qPloneComments'] 
     70        value =  prop_sheet.getProperty('enable_anonymous_report_abuse', False) 
     71        return value 
     72 
     73    def ajax_report_abuse_enabled(self): 
     74        """ """ 
     75        portal_properties = getToolByName(self.context, 'portal_properties') 
     76        prop_sheet = portal_properties['qPloneComments'] 
     77        value =  prop_sheet.getProperty('enable_ajax_report_abuse', False) 
     78        return value 
     79 
     80    def email_from_address(self): 
     81        """ """ 
     82        portal_url = getToolByName(self.context, 'portal_url') 
     83        portal = portal_url.getPortalObject() 
     84        return portal.email_from_address 
     85 
     86    def member(self): 
     87        """ """ 
     88        pm = getToolByName(self.context, 'portal_membership') 
     89        return pm.getAuthenticatedMember() 
     90 
     91    def tabindex(self): 
     92        """ Needed for BBB, tabindex has been deprecated. 
     93        """ 
     94        return IndexIterator() 
     95 
     96    def portal_url(self): 
     97        """ """ 
     98        return getToolByName(self.context, 'portal_url') 
     99 
     100 
     101 
     102class CommentsKSS(PloneKSSView): 
     103    """ Operations on the report abuse form using KSS. 
     104    """    
     105 
     106    def submit_abuse_report(self): 
     107        """ Send an email with the abuse report message and hide abuse report form. 
     108        """ 
     109        errors = {} 
     110        context = aq_inner(self.context) 
     111        request = context.REQUEST 
     112        portal = getToolByName(self.context, 'portal_url').getPortalObject() 
     113        if hasattr(context, 'captcha_validator'): 
     114            dummy_controller_state = ControllerState( 
     115                                            id='comments.pt', 
     116                                            context=context, 
     117                                            button='submit', 
     118                                            status='success', 
     119                                            errors={}, 
     120                                            next_action=None,) 
     121            # get the form controller 
     122            controller = portal.portal_form_controller 
     123            # send the validate script to the form controller with the dummy state object 
     124            controller_state = controller.validate(dummy_controller_state, request, ['captcha_validator',]) 
     125            errors.update(controller_state.errors) 
     126 
     127        message = request.get('message') 
     128        if not message: 
     129            errors.update({'message': 'Please provide a message'}) 
     130 
     131        mtool = getToolByName(self.context, "portal_membership") 
     132        member = mtool.getAuthenticatedMember() 
     133        comment_id = self.context.request.get('comment_id') 
     134        ksscore = self.getCommandSet('core') 
     135        if errors: 
     136            html = self.macroContent('context/report_abuse_form/macros/form', 
     137                                     errors=errors, 
     138                                     show_form=True, 
     139                                     tabindex=IndexIterator(), 
     140                                     member=member, 
     141                                     **request.form) 
     142            node = ksscore.getHtmlIdSelector('span-reply-form-holder-%s' % comment_id) 
     143            ksscore.replaceInnerHTML(node,  html) 
     144            return self.render() 
     145 
     146        # report_abuse(context, context, message, comment) 
     147        manage_mails(context, self.context, 'report_abuse') 
     148 
     149        html = self.macroContent('context/report_abuse_form/macros/form', 
     150                                 tabindex=IndexIterator(), 
     151                                 member=member, 
     152                                 **request.form) 
     153        node = ksscore.getHtmlIdSelector('span-reply-form-holder-%s' % comment_id) 
     154        html = '<br/><span style="color:red">You have reported this comment for abuse.</span>' 
     155        self.commands.addCommand('remove_abuse_report_form',  
     156                                 node,  
     157                                 comment_id=comment_id,  
     158                                 html=html) 
     159 
     160        node = ksscore.getHtmlIdSelector('div-captcha-%s' % comment_id) 
     161        html = self.macroContent('context/report_abuse_form/macros/captcha', 
     162                                 **request.form) 
     163        ksscore.replaceInnerHTML(node,  html) 
     164        return self.render() 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/browser/configure.zcml

    r820 r1201  
    22    xmlns="http://namespaces.zope.org/zope" 
    33    xmlns:browser="http://namespaces.zope.org/browser" 
     4    xmlns:kss="http://namespaces.zope.org/kss" 
    45    i18n_domain="quintagroup.plonecomments"> 
    56 
     7    <browser:page 
     8        for="*" 
     9        attribute="submit_abuse_report" 
     10        class=".comments.CommentsKSS" 
     11        name="kss_submit_abuse_report" 
     12        permission="zope2.View" 
     13        />  
     14 
     15    <kss:action 
     16        name="remove_abuse_report_form" 
     17        command_factory="selector" 
     18        jsfile="../skins/quintagroup_plonecomments/qcomments.js" 
     19        /> 
     20 
    621</configure> 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/configure.zcml

    r832 r1201  
    66    i18n_domain="quintagroup.plonecomments"> 
    77 
    8   <five:registerPackage package="." /> 
    9   <i18n:registerTranslations directory="locales" /> 
     8    <five:registerPackage package="." /> 
    109 
    11   <include package="plone.browserlayer" /> 
    12   <include package=".browser" /> 
    13   <include file="skins.zcml" /> 
    14   <include file="profiles.zcml" /> 
     10    <include package="plone.browserlayer" /> 
     11    <include package=".browser" /> 
     12    <include file="skins.zcml" /> 
     13    <include file="profiles.zcml" /> 
    1514 
    16   <permission 
    17       id="moderate.discussion" 
    18       title="Moderate Discussion" 
    19       /> 
     15    <i18n:registerTranslations directory="locales" /> 
     16 
     17    <permission 
     18        id="moderate.discussion" 
     19        title="Moderate Discussion" 
     20        /> 
    2021 
    2122</configure> 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/profiles/default/propertiestool.xml

    r822 r1201  
    11<?xml version="1.0"?> 
    2 <object name="portal_properties"> 
     2<object name="portal_properties" 
     3    xmlns:i18n="http://xml.zope.org/namespaces/i18n" 
     4    i18n:domain="quintagroup.plonecomments"> 
    35 <object name="qPloneComments" meta_type="Plone Property Sheet"> 
    46  <property name="title">qPloneComments properties</property> 
     
    1113  <property name="enable_published_notification" type="boolean">True</property> 
    1214  <property name="enable_approve_notification" type="boolean">True</property> 
     15  <property name="enable_authenticated_report_abuse" type="boolean">True</property> 
     16  <property name="enable_anonymous_report_abuse" type="boolean">True</property> 
     17  <property name="enable_ajax_report_abuse" type="boolean">False</property> 
    1318  <property name="email_discussion_manager" type="string"></property> 
    1419  <property name="email_subject_prefix" type="string"></property> 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/skins/quintagroup_plonecomments/prefs_comments_setup_form.cpt

    r822 r1201  
    113113                    <label i18n:translate="label_anonymous_commenting"  
    114114                           for="isEnabledAnonymousCommenting">Allow comments from Anonymous users</label> 
     115                </div> 
     116 
     117                <div class="field" 
     118                     tal:define="property_id string:enable_authenticated_report_abuse; 
     119                                 isEnabledReportAbuse python:props_sheet.getProperty(property_id, False);" 
     120                     tal:condition="python:props_sheet.hasProperty(property_id)"> 
     121 
     122                    <input type="checkbox"  
     123                           class="noborder" 
     124                           name="isEnabledReportAbuse" 
     125                           id="isEnabledReportAbuse" 
     126                           tabindex ="" 
     127                           tal:attributes="name property_id; 
     128                                           value isEnabledReportAbuse; 
     129                                           checked python:test(isEnabledReportAbuse, 'True', ''); 
     130                                           tabindex tabindex/next;"/> 
     131 
     132                    <label i18n:translate="label_enable_report_abuse" 
     133                           for="isEnabledReportAbuse">Enable authenticated users to report abusive comments</label> 
     134                </div> 
     135 
     136                <div class="field" 
     137                     tal:define="property_id string:enable_anonymous_report_abuse; 
     138                                 isEnabledAnonymousReportAbuse python:props_sheet.getProperty(property_id, False);" 
     139                     tal:condition="python:props_sheet.hasProperty(property_id)"> 
     140 
     141                    <input type="checkbox"  
     142                           class="noborder" 
     143                           name="isEnabledAnonymousReportAbuse" 
     144                           id="isEnabledAnonymousReportAbuse" 
     145                           tabindex ="" 
     146                           tal:attributes="name property_id; 
     147                                           value isEnabledAnonymousReportAbuse; 
     148                                           checked python:test(isEnabledAnonymousReportAbuse, 'True', ''); 
     149                                           tabindex tabindex/next;"/> 
     150 
     151                    <label i18n:translate="label_enable_anonymous_report_abuse" 
     152                           for="isEnabledAnonymousReportAbuse">Enable anonymous users to report abusive comments</label> 
     153 
     154                    <div class="formHelp" id="anonymous_report_abuse_help" 
     155                         i18n:translate="help_enable_anonymous_report_abuse"> 
     156                        This setting will allow ALL users, including non logged in users to report abusive comments. 
     157                    </div> 
     158                </div> 
     159 
     160                <div class="field" 
     161                     tal:define="property_id string:enable_ajax_report_abuse; 
     162                                 isEnabledAjaxReportAbuse python:props_sheet.getProperty(property_id, False);" 
     163                     tal:condition="python:props_sheet.hasProperty(property_id)"> 
     164 
     165                    <input type="checkbox"  
     166                           class="noborder" 
     167                           name="isEnabledAjaxReportAbuse" 
     168                           id="isEnabledAjaxReportAbuse" 
     169                           tabindex ="" 
     170                           tal:attributes="name property_id; 
     171                                           value isEnabledAjaxReportAbuse; 
     172                                           checked python:test(isEnabledAjaxReportAbuse, 'True', ''); 
     173                                           tabindex tabindex/next;"/> 
     174 
     175                    <label i18n:translate="label_enable_ajax_report_abuse" 
     176                           for="isEnabledAjaxReportAbuse">Enable AJAX powered abuse reports</label> 
     177 
     178                    <div class="formHelp" id="ajax_report_abuse_help" 
     179                         i18n:translate="help_enable_ajax_report_abuse"> 
     180                        This setting will only take effect if abuse reports are enabled. 
     181                    </div> 
    115182                </div> 
    116183 
  • quintagroup.plonecomments/trunk/quintagroup/plonecomments/utils.py

    r1058 r1201  
     1import smtplib 
    12from Products.CMFPlone import MessageFactory 
    23from Products.CMFCore.utils import getToolByName 
     4from Products.CMFPlone import PloneMessageFactory as _ 
     5from config import warning 
    36 
    47# Get apropriate property from (propery_sheeet) configlet 
     
    3841                              'enable_published_notification'), 
    3942                'onDelete' :  ('enable_rejected_user_notification',), 
    40                 'onApprove': ('enable_approve_notification',)} 
     43                'onApprove': ('enable_approve_notification',), 
     44                'onAnonymousReportAbuse': ('enable_anonymous_report_abuse',), 
     45                'onAuthenticatedReportAbuse': ('enable_authenticated_report_abuse')} 
    4146 
    4247    if action == 'publishing': 
     
    4853    elif action == 'aproving': 
    4954        sendMails(props, actions, 'onApprove') 
     55 
     56    elif action == 'report_abuse': 
     57        pm = getToolByName(context, 'portal_membership') 
     58        if pm.isAnonymousUser(): 
     59            sendMails(props, actions, 'onAnonymousReportAbuse') 
     60        else: 
     61            sendMails(props, actions, 'onAuthenticatedReportAbuse') 
    5062 
    5163def getMsg(context, template, args): 
     
    163175            args = {} 
    164176 
     177    elif state in ('enable_authenticated_report_abuse', 'enable_anonymous_report_abuse'): 
     178        template = 'report_abuse_template' 
     179        user_email = getProp(context, "email_discussion_manager", None) 
     180        if user_email: 
     181            message = context.REQUEST.get('message') 
     182            comment_id = context.REQUEST.get('comment_id') 
     183            pd = context.portal_discussion 
     184            dl = pd.getDiscussionFor(context) 
     185            comment = dl._container.get(comment_id) 
     186            args = {'mto': user_email, 
     187                    'mfrom': admin_email, 
     188                    'obj': reply_parent, 
     189                    'message':message, 
     190                    'organization_name': organization_name, 
     191                    'name': creator_name, 
     192                    'comment_id':comment_id, 
     193                    'comment_desc':comment.description, 
     194                    'comment_text':comment.text 
     195                    } 
     196            subject = '[%s] A comment on "%s" has been reported for abuse.' \ 
     197                            % (organization_name, getParent(context).Title()) 
     198        else: 
     199            args = {} 
     200 
    165201    if args: 
    166202        msg = getMsg(context, template, args) 
     
    168204        site_props = context.portal_properties.site_properties 
    169205        host = p_utils.getMailHost() 
    170         host.secureSend(msg, user_email, admin_email, 
    171                         subject = subject, 
    172                         subtype = 'plain', 
    173                         debug = False, 
    174                         charset = site_props.getProperty('default_charset', 'utf-8'), 
    175                         From = admin_email) 
     206        try: 
     207            host.secureSend(msg, user_email, admin_email, 
     208                            subject = subject, 
     209                            subtype = 'plain', 
     210                            debug = False, 
     211                            charset = site_props.getProperty('default_charset', 'utf-8'), 
     212                            From = admin_email) 
     213        except smtplib.SMTPRecipientsRefused: 
     214            log.error(_('SMTPRecipientsRefused: Could not send the email' 
     215            'notification. Have you configured an email server for Plone?')) 
    176216 
    177217def setStatusMsg(state, context, msg): 
Note: See TracChangeset for help on using the changeset viewer.