Commits

Julio Flores-Schwarzbeck committed 8cbbac2

Some PEP-8 updates, addition of offensive flagging of comments and
answers, and overall adminstrative section enhancements, still
considered early-beta code unless admin uses te DB directly

Comments (0)

Files changed (8)

controllers/admin.py

         db.admin_messages.ALL)[0]
     # In addition, update this message's status to "read"
     db(db.admin_messages.id==request.args[0]).update(read_flag=True)
-    return dict(message=message)
+    return dict(message=message)
+
+@auth_user.requires_role('SysAdmin')
+def qa_mgmt():
+    # Get the counts for the different types of "problematic" questions
+    # and answers.
+    
+    return dict()

controllers/members.py

                     # Google authentication was correct, auhenticate_google()
                     # Will simply return "True" if the (already authenticated)
                     # user had an account already in QA-Stack, or False if
-                    # qa-stack had to create the record entry for the first time
+                    # qa-stack had to create the record entry for the
+                    # first time
                     auth_user.authenticate_google(req.auth_alias, req.passwd)
                     isauth = True
                 else:
             name,
             email,
             profile_pic_url)
-        vars={}
+        form_vars = {}
 
         # Now, update some properties
         stackhelper.put_member_property('m_last_login', user_id, request.now)
     else:
         # TODO: Do something more elegant than this
         #raise ValueError('An error occured: %s' % (auth_info['err']['msg']))
-        vars = dict(login_error=auth_info['err']['msg'])
-    redirect(URL(r=request, c='default', f='index', vars=vars))
+        form_vars = dict(login_error=auth_info['err']['msg'])
+    redirect(URL(r=request, c='default', f='index', vars=form_vars))
 
 
 @auth_user.requires_login()
                             user_id=user_id,
                             question_subscriptions=question_subscriptions)
             else:
-                redirect(URL(r=request, c='members', f='preferences', vars=dict(saved=1)))
+                redirect(URL(
+                    r=request,
+                    c='members',
+                    f='preferences',
+                    vars=dict(saved=1)))
         else:
             redirect(URL(r=request, c='default', f='index'))
     else:
                     # Update the question's last update date/user
                     db(db.questions.id==qid).update(modified_by=modified_by,
                                                     modified_on=request.now)
-                    # Also, increment the number of questions this user has posted
+                    # Also, increment the number of questions
+                    # this user has posted
                     stackhelper.increment_member_property('m_comments',
                                                           modified_by,
                                                           1)
                     # Update the original question's last update date/user
                     db(db.questions.id==qid).update(modified_by=modified_by,
                                                     modified_on=request.now)
-                    # Also, increment the number of questions this user has posted
+                    # Also, increment the number of questions this user
+                    # has posted
                     stackhelper.increment_member_property('m_comments',
                                                           modified_by,
                                                           1)
             if auth_user.has_role('Manager,SysAdmin'):
                 score_log_insert = True
             else:
-                # Here is when things get a little iffy, in this scenario, you may:
-                # DOWNVOTE: Only if you have no previous record of up/dn vote for
-                #           this particular record (question/answer/comment), OR
+                # Here is when things get a little iffy, in this scenario,
+                # you may:
+                # DOWNVOTE: Only if you have no previous record of
+                # up/dn vote for
+                #           this particular record (question/answer/comment),OR
                 #           you have previously UPVOTED this particular record.
                 # UPVOTE: Only if you have no previous record of up/dn vote for
                 #         this particular record (question/answer/comment), OR
                     if upvotes > dnvotes:
                         err = 1 # You may not up vote the same question twice
                     elif upvotes == dnvotes and upvotes == 1:
-                        err = 2 # You may not vote up or down anymore for this Q
+                        err = 2 # You may not vote up or down anymore 4 this Q
                     else:
                         # Allow Upvoting
                         score_log_insert = True
                     # In addition, update the auth_role_id of the user that will
                     # receive the "points"
                     # Note, to this version, only up/dn votes on questions and
-                    # answers are awarded points to matter for the user's profile
+                    # answers are awarded points to matter for the user's prof.
                     # Comments do not. (this coud change though)
                     # Also here update the user's appropriate fields pertaining
                     # points
     if session.has_key('lang'):
         del session['lang']
     auth_user.logout()
-    redirect(URL(r=request, c='default', f='index', vars=dict(lang='')))
+    redirect(URL(r=request, c='default', f='index', vars=dict(lang='')))
+    
+def flag_entry():
+    # Creates an administrator message crafted specifically to inform
+    # them of a possible offensive comment or answer posted by a jackass
+    # entry_id is either answer_id or comment_id
+    # question_id is as its name implies
+    # entry_type is either 'comment', or 'answer'
+    entry_id, question_id, entry_type = request.args
+    # Cannot be None since caller is auth
+    user_id = auth_user.get_user_id()
+    user_name = stackhelper.get_member_property('m_display_name',
+                                                user_id, '') or \
+              auth_user.get_user_name() 
+    redirect_url = URL(r=request, c='default', f='view', args=[question_id])
+    user_id_url = URL(r=request, c='admin', f='edit_user', args=[user_id])
+    if entry_type == 'answer':
+        entry = db(db.answers.id==entry_id).select(db.answers.ALL)[0]
+    else:
+        entry = db(db.comments.id==entry_id).select(db.comments.ALL)[0]
+    message = """<a href="%s" title="">%s</a> has reported an inappropriate
+    %s. The contents of the %s are:
+    
+    %s
+    
+    Question Location: <a href="%s" title="">%s</a>
+    """ % (user_id_url,
+           user_name,
+           entry_type,
+           entry_type,
+           entry.description,
+           redirect_url,
+           redirect_url)
+    db.admin_messages.insert(
+        auth_user_id=user_id,
+        subject="Inappropriate %s reported by %s" % (entry_type, user_name),
+        message=parse_content(message),
+        creation_date=request.now,
+        read_flag=False)
+    redirect(redirect_url)
 def handle_pygments(pat, content, pygments_lexer):
     data = pat.search(content)
     while data:
-        code_found = highlight(data.group(2), pygments_lexer(), HtmlFormatter(noclasses=True));
+        code_found = highlight(data.group(2), pygments_lexer(),
+                               HtmlFormatter(noclasses=True));
         # This is needed to the global conversion to '<br />'s later on applies
         # to highlighted code as well.
         code_found = code_found.replace('<br />', '\n')
         # JavaLexer
         try:
             if clean_content.find('[code-python]') >= 0:
-                pat = re.compile(r'(\[code-python\])(.*?)(\[/code-python\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-python\])(.*?)(\[/code-python\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, PythonLexer)
             if clean_content.find('[code-c#]') >= 0:
-                pat = re.compile(r'(\[code-c#\])(.*?)(\[/code-c#\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-c#\])(.*?)(\[/code-c#\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, CSharpLexer)
             if clean_content.find('[code-c]') >= 0:
-                pat = re.compile(r'(\[code-c\])(.*?)(\[/code-c\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-c\])(.*?)(\[/code-c\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, CLexer)
             if clean_content.find('[code-c++]') >= 0:
-                pat = re.compile(r'(\[code-c\+\+\])(.*?)(\[/code-c\+\+\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-c\+\+\])(.*?)(\[/code-c\+\+\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, CppLexer)
             if clean_content.find('[code-java]') >= 0:
-                pat = re.compile(r'(\[code-java\])(.*?)(\[/code-java\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-java\])(.*?)(\[/code-java\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, JavaLexer)
             if clean_content.find('[code-php]') >= 0:
-                pat = re.compile(r'(\[code-php\])(.*?)(\[/code-php\])', re.DOTALL |  re.IGNORECASE | re.MULTILINE)
+                pat = re.compile(r'(\[code-php\])(.*?)(\[/code-php\])',
+                                 re.DOTALL |  re.IGNORECASE | re.MULTILINE)
                 clean_content = handle_pygments(pat, clean_content, PhpLexer)
             if clean_content.find('[code]') >= 0:
                 clean_content = clean_content.replace('[code]', '<pre>')

modules/QAStackHelper.py

         it returns a boolean value describing success in adding the property
         or failure when the prioperty could not be updated """
         if self.auth_user.is_admin(): # <-- May not be needed
-            prop = self.db(self.db.system_properties.property_name==property_name
-                           ).select(self.db.system_properties.id)
+            prop = self.db(self.db.system_properties.property_name==\
+                           property_name).select(self.db.system_properties.id)
             if prop:
                 prop_id = prop[0].id
                 self.db(self.db.system_properties.id==prop_id
         user_property_value = default_value
         # First check if the property exists
         property_check = self.db(
-            self.db.member_properties_skel.property_name==property_name).select(
-            self.db.member_properties_skel.id)
+            self.db.member_properties_skel.property_name==\
+            property_name).select(self.db.member_properties_skel.id)
         if property_check:
             property_id = property_check[0].id
             user_prop = self.db(
 
     def has_question_subscription(self, question_id, user_id):
         has_s = self.db((self.db.question_subscriptions.auth_user_id==user_id) &\
-                        (self.db.question_subscriptions.question_id==question_id
-                         )).count() > 0
+                        (self.db.question_subscriptions.question_id==\
+                         question_id)).count() > 0
         return has_s
 
     def add_question_subscription(self, question_id, user_id):
         except ValueError:
             new_user_role_idx = -1 # Unknown Role
 
-        #raise ValueError(user_role, new_user_role,user_role_idx,new_user_role_idx,)
-
         # Only update if the new user role is greater than the previous one
         if new_user_role_idx > user_role_idx:
             # Get the primary key for this role:

static/qastack_stylesheet.css

     font-size:90%;
     font-weight:bold;
     color:teal;
-    border-bottom:1px solid teal;
+    /*  border-bottom:1px solid teal; */
 }
 
 div.info-pretty {

views/admin/index.html

                                     Anonymous
                                 {{else:}}
                                     <a title="Edit this User"
-                                        href="{{=URL(r=request, c='admin', f='edit_user', args=[3])}}"
+                                        href="{{=URL(r=request, c='admin', f='edit_user', args=[message.admin_messages.auth_user_id])}}"
                                         >{{=stackhelper.get_member_property('m_display_name', message.admin_messages.auth_user_id, 'Unknown User')}}</a>
                                 {{pass}}
                             </td>

views/admin/qa_mgmt.html

+{{extend 'qastack_layout.html'}}
+{{include 'admin_common.html'}}
+
+<script type="text/javascript">
+<!--
+     document.getElementById('aadmin').className = 'active';
+//-->
+
+</script>
+
+<h2 class="fancy">Administrative Messages - Q&amp;A Management</h2>
+

views/default/view.html

                                     {{=XML(T('Accepted Answer'))}}
                                 </div>
                             {{pass}}
-                            <!-- owner or admin options... //-->
+                            <!-- owner, admin or member options... //-->
                             <div class="info" style="margin-bottom:10px;">
                                 {{if auth_user.has_role('Reviewer,TeamLead,Manager,SysAdmin'):}}
                                     <a href="{{=URL(r=request, c='members', f='comment_answer',
                                        onclick="return confirm('This will change the answer status for this question, Please Confirm');"
                                        class="bold">{{=XML(T('Accept this Answer'))}}</a>
                                 {{pass}}
+                                {{if auth_user.is_auth():}}
+                                    |
+                                    <a title=""
+                                    href="{{=URL(r=request, c='members', f='flag_entry', args=[answer.answers.id, question.questions.id, 'answer'])}}"
+                                    onclick="return confirm('This will flag this answer for removal by the administrators\n\nPlease Confirm.');"
+                                    class="bold">Report as Offensive</a>
+                                {{pass}}
                             </div>
                             <span class="explain"><a name="answer_{{=answer.answers.id}}">{{=XML(T('By'))}}: {{=answer.member_properties.property_value}}
                             ({{=stackhelper.get_user_role(answer.answers.modified_by)}}),
                                                 ({{=stackhelper.get_user_role(comment.comments.modified_by)}})</a>,
                                                 {{=XML(T('Updated'))}}: {{=prettydate(comment.comments.modified_on, T)}},
                                                 {{=XML(T('Votes'))}}: {{=comment.comments.votes_up - comment.comments.votes_dn}}
+                                                {{if auth_user.is_auth():}}                                    |
+                                                    <a title=""
+                                                    href="{{=URL(r=request, c='members', f='flag_entry', args=[comment.comments.id, question.questions.id, 'comment'])}}"
+                                                    onclick="return confirm('This will flag this comment for removal by the administrators\n\nPlease Confirm.');"
+                                                    class="bold">Report as Offensive</a>
+                                                {{pass}}
                                             </div>
                                             <div class="pad-comment">{{=XML(parse_content(comment.comments.description))}}</div>
                                         </td>