[odrs-web/production] Make moderation easier



commit c1ca38c2f852345ec9df279a46295f4a78ee7ff8
Author: Richard Hughes <richard hughsie com>
Date:   Fri Jul 7 21:55:56 2017 +0100

    Make moderation easier

 app/templates/default.html |    6 +-
 app/templates/mods.html    |   34 ++++++-----
 app/templates/show.html    |  143 +++++++++++++++++++++++---------------------
 app/views_admin.py         |  115 ++++++++++++++++++++++++++++++-----
 4 files changed, 196 insertions(+), 102 deletions(-)
---
diff --git a/app/templates/default.html b/app/templates/default.html
index 6dd525a..668c79b 100644
--- a/app/templates/default.html
+++ b/app/templates/default.html
@@ -38,6 +38,7 @@
               <li><a href="/">Home</a></li>
               <li><a href="/admin/show/all">All Reviews</a></li>
 {% if current_user.is_authenticated %}
+              <li><a href="/admin/show/unmoderated">Queue</a></li>
               <li><a href="/admin/show/reported">Reported</a></li>
 {% endif %}
 {% if current_user.is_admin %}
@@ -46,8 +47,6 @@
               <li><a href="/admin/moderators/all">Moderators</a></li>
               <li><a href="/admin/distros">Distributions</a></li>
               <li><a href="/admin/graph_month">Usage</a></li>
-{% else %}
-              <li><a href="/admin/moderator/{{current_user.username}}/admin">Profile</a></li>
 {% endif %}
             </ul>
           </div>
@@ -55,6 +54,9 @@
         <div class="right">
           <div class="menu-globalnav-container">
             <ul id="menu-globalnav" class="menu">
+{% if not current_user.is_admin and current_user.is_authenticated %}
+              <li><a href="/admin/moderator/{{current_user.username}}/admin">Profile</a></li>
+{% endif %}
 {% if current_user.is_authenticated %}
               <li class="navigation2"><a href="/logout">Logout</a></li>
 {% else %}
diff --git a/app/templates/mods.html b/app/templates/mods.html
index d96adcc..a6b0e0b 100644
--- a/app/templates/mods.html
+++ b/app/templates/mods.html
@@ -29,22 +29,24 @@
 
 <h2>Create new</h2>
 <form method="post" action="/admin/moderator/add" class="form">
-  <div class="form-control">
-    <label for="username_new">Username:</label>
-    <input type="text" class="form-control" name="username_new" required>
-  </div>
-  <div class="form-control">
-    <label for="password_new">Password:</label>
-    <input type="password" class="form-control" name="password_new" required>
-  </div>
-  <div class="form-control">
-    <label for="name">Display Name:</label>
-    <input type="text" class="form-control" name="display_name" required>
-  </div>
-  <div class="form-control">
-    <label for="email">Contact Email:</label>
-    <input type="text" class="form-control" name="email" required>
-  </div>
+<table>
+  <tr>
+    <th>Username:</th>
+    <td><input type="text" class="form-control" name="username_new" required></td>
+  </tr>
+  <tr>
+    <th>Password:</th>
+    <td><input type="password" class="form-control" name="password_new" required></td>
+  </tr>
+  <tr>
+    <th>Display Name:</th>
+    <td><input type="text" class="form-control" name="display_name" required></td>
+  </tr>
+  <tr>
+    <th>Contact Email:</th>
+    <td><input type="text" class="form-control" name="email" required></td>
+  </tr>
+</table>
   <input type="submit" value="Add">
 </form>
 
diff --git a/app/templates/show.html b/app/templates/show.html
index 409102a..30e6a65 100644
--- a/app/templates/show.html
+++ b/app/templates/show.html
@@ -3,83 +3,100 @@
 
 {% block content %}
 
+<a href="/admin/review/{{ r.review_id - 1 }}">
+  <button class="action" type="button">&lt;&lt;</button>
+</a>
+<a href="/admin/review/{{ r.review_id + 1 }}">
+  <button class="action" type="button">&gt;&gt;</button>
+</a>
+
 <form name="myform" action="/admin/modify/{{ r.review_id }}" method="POST">
 <table>
-  <tr>
-    <th>Application</th>
-    <td>
-      <textarea cols="40" rows="1" name="app_id">{{ r.app_id }}</textarea>
+
+<br/>
 {% if current_user.is_authenticated %}
-      <a href="/admin/show/app/{{ r.app_id }}">
-        <button class="inline" type="button">Show All</button>
+  <tr>
+    <th>Actions</th>
+    <td colspan="5">
+{% if current_user.user_hash and not vote_exists %}
+      <a href="/admin/vote/{{r.review_id}}/up">
+        <button class="action" type="button">Vote Up</button>
+      </a>
+      <a href="/admin/vote/{{r.review_id}}/down">
+        <button class="action" type="button">Vote Down</button>
+      </a>
+      <a href="/admin/vote/{{r.review_id}}/meh">
+        <button class="action" type="button">Meh</button>
       </a>
 {% endif %}
+      <a href="/admin/delete/{{r.review_id}}">
+        <button class="destructive-action" type="submit">Remove Forever</button>
+      </a>
     </td>
   </tr>
+{% endif %}
   <tr>
-    <th>Rating</th>
-    <td>{{ format_rating(r.rating) }}</td>
-  </tr>
-  <tr>
-    <th>Created</th>
-    <td>{{ format_timestamp(r.date_created) }}</td>
-  </tr>
-  <tr>
-    <th>Removed</th>
-    <td>
-      {{ format_timestamp(r.date_deleted) }}
+    <th>Application</th>
+    <td colspan="5">
+      <textarea cols="75" rows="1" name="app_id">{{ r.app_id }}</textarea>
 {% if current_user.is_authenticated %}
-{% if r.date_deleted %}
-      <a href="/admin/unremove/{{ r.review_id }}">
-        <button class="inline" type="button">Unremove</button>
+      <a href="/admin/show/app/{{ r.app_id }}">
+        <button class="inline" type="button">All</button>
       </a>
 {% endif %}
-{% endif %}
     </td>
   </tr>
   <tr>
+    <th>Rating</th>
+    <td>{{ format_rating(r.rating) }}</td>
     <th>Karma</th>
-    <td>{{ r.karma_up }}&uarr;, {{ r.karma_down }}&darr;</td>
-  </tr>
-  <tr>
-    <th>Reported</th>
     <td>
-      {{ r.reported }}
-{% if current_user.is_authenticated %}
+      {{ r.karma_up }}&uarr;, {{ r.karma_down }}&darr;
 {% if r.reported > 0 %}
+      (reported {{ r.reported }})
+{% if current_user.is_authenticated %}
       <a href="/admin/unreport/{{ r.review_id }}">
         <button class="inline" type="button">Unreport</button>
       </a>
-      <a href="/admin/user_ban/{{ r.user_hash }}">
-        <button class="inline" type="button">Ban User</button>
-      </a>
 {% endif %}
 {% endif %}
     </td>
-  </tr>
-  <tr>
-    <th>User Hash</th>
+    <th>Created</th>
     <td>
-      <textarea cols="40" rows="1" name="user_hash">{{ r.user_hash }}</textarea>
+      {{ format_timestamp(r.date_created) }}
+{% if r.date_deleted %}
+      (deleted {{ format_timestamp(r.date_deleted) }})
 {% if current_user.is_authenticated %}
-      <a href="/admin/show/user/{{ r.user_hash }}">
-        <button class="inline" type="button">Show All</button>
+      <a href="/admin/unremove/{{ r.review_id }}">
+        <button class="inline" type="button">Unremove</button>
       </a>
 {% endif %}
+{% endif %}
     </td>
   </tr>
   <tr>
     <th>User Display</th>
-    <td>
+    <td colspan="5">
 {% if r.user_display %}
-      <textarea cols="40" rows="1" name="user_display">{{ r.user_display }}</textarea>
+{% if current_user.is_authenticated %}
+      <em>Names cannot be offensive or trademarks<br/></em>
+{% endif %}
+      <textarea cols="60" rows="1" name="user_display">{{ r.user_display }}</textarea>
 {% if current_user.is_authenticated %}
       <a href="/admin/anonify/{{ r.review_id }}">
         <button class="inline" type="button">Anonify</button>
       </a>
 {% endif %}
 {% else %}
-      <textarea cols="40" rows="1" name="user_display"></textarea>
+      <textarea cols="20" rows="1" name="user_display"></textarea>
+{% endif %}
+{% if current_user.is_authenticated %}
+      <a href="/admin/show/user/{{ r.user_hash }}">
+        <button class="inline" type="button">All</button>
+      </a>
+      <a href="/admin/user_ban/{{ r.user_hash }}">
+        <button class="inline" type="button">Ban</button>
+      </a>
 {% endif %}
     </td>
   </tr>
@@ -89,7 +106,7 @@
       <textarea cols="10" rows="1" name="locale">{{ r.locale }}</textarea>
 {% if current_user.is_authenticated %}
       <a href="/admin/show/lang/{{ r.locale }}">
-        <button class="inline" type="button">Show All</button>
+        <button class="inline" type="button">All</button>
       </a>
 {% if not r.locale.startswith('en_') %}
       <a href="/admin/englishify/{{ r.review_id }}">
@@ -98,55 +115,45 @@
 {% endif %}
 {% endif %}
     </td>
-  </tr>
-  <tr>
     <th>Version</th>
     <td>
-      <textarea cols="80" rows="1" name="version">{{ r.version }}</textarea>
+      <textarea cols="15" rows="1" name="version">{{ r.version }}</textarea>
     </td>
+<!--
   </tr>
   <tr>
+-->
     <th>Distro</th>
     <td>
-      <textarea cols="80" rows="1" name="distro">{{ r.distro }}</textarea>
+      <textarea cols="15" rows="1" name="distro">{{ r.distro }}</textarea>
     </td>
   </tr>
   <tr>
     <th>Summary</th>
-    <td>
-      <em>This should start with a capital and not end with a full stop</em>
+    <td colspan="5">
+{% if current_user.is_authenticated %}
+      <em>This should start with a capital letter and not end with a full stop</em><br/>
+{% endif %}
       <textarea cols="80" rows="1" name="summary">{{ r.summary }}</textarea>
     </td>
   </tr>
   <tr>
     <th>Description</th>
-    <td>
+    <td colspan="5">
+{% if current_user.is_authenticated %}
       <em>
-        This should start with a capital and each sentance should end with a full stop.<br/>
-        Please remove any incorrect content, and correct spelling, and grammar where required.</em>
+        This should start with a capital letter and each sentance should end with a full stop.<br/>
+        Please remove any incorrect content, and correct spelling, and grammar where required.
+      </em><br/>
+{% endif %}
       <textarea cols="80" rows="20" name="description">{{ r.description }}</textarea>
+      <br/>
+{% if current_user.is_authenticated %}
+      <button class="action" type="submit">Modify</button>
+{% endif %}
     </td>
   </tr>
 </table>
-
-{% if current_user.is_authenticated %}
-<button class="action" type="submit">Modify</button>
-{% endif %}
-
 </form>
 
-<a href="/admin/review/{{ r.review_id + 1 }}">
-<button class="action" type="button">Next</button>
-</a>
-<a href="/admin/review/{{ r.review_id - 1 }}">
-<button class="action" type="button">Previous</button>
-</a>
-
-{% if current_user.is_authenticated %}
-<a href="/admin/delete/{{ r.review_id }}">
-<button class="destructive-action" type="submit">Delete</button>
-</a>
-
-{% endif %}
-
 {% endblock %}
diff --git a/app/views_admin.py b/app/views_admin.py
index e7d2487..a42bc9f 100644
--- a/app/views_admin.py
+++ b/app/views_admin.py
@@ -36,6 +36,26 @@ def _get_chart_labels_days():
         labels.append("%02i-%02i-%02i" % (then.year, then.month, then.day))
     return labels
 
+def _get_langs_for_user(user):
+    if not user:
+        return None
+    if not getattr(user, 'locales', None):
+        return None
+    if not user.locales:
+        return None
+    if user.locales == '*':
+        return None
+    return user.locales.split(',')
+
+def _get_hash_for_user(user):
+    if not user:
+        return None
+    if not getattr(user, 'user_hash', None):
+        return None
+    if not user.user_hash:
+        return None
+    return user.user_hash
+
 def _password_check(value):
     """ Check the password for suitability """
     success = True
@@ -234,7 +254,15 @@ def admin_show_review(review_id):
         return _error_internal(str(e))
     if not review:
         return _error_internal('no review with that ID')
-    return render_template('show.html', r=review)
+
+    # has the user already voted
+    user_hash = _get_hash_for_user(current_user)
+    if user_hash:
+        vote_exists = db.reviews.vote_exists(review_id, user_hash)
+    else:
+        vote_exists = False
+
+    return render_template('show.html', r=review, vote_exists=vote_exists)
 
 @app.route('/admin/modify/<review_id>', methods=['POST'])
 @login_required
@@ -367,23 +395,12 @@ def admin_show_all(page):
 
     try:
         db = get_db()
-        reviews_all = db.reviews.get_all()
+        reviews = db.reviews.get_all()
     except CursorError as e:
         return _error_internal(str(e))
-    if not reviews_all and page != 1:
+    if not reviews and page != 1:
         abort(404)
 
-    # filter by the languages the moderator understands
-    reviews = []
-    if not current_user or current_user.locales == None or current_user.locales == '*':
-        reviews.extend(reviews_all)
-    else:
-        langs = current_user.locales.split(',')
-        for r in reviews_all:
-            lang = r.locale.split('_')[0]
-            if lang in langs:
-                reviews.append(r)
-
     reviews_per_page = 20
     pagination = Pagination(page, reviews_per_page, len(reviews))
     # FIXME: do this database side...
@@ -392,6 +409,41 @@ def admin_show_all(page):
                            pagination=pagination,
                            reviews=reviews)
 
+@app.route('/admin/show/unmoderated')
+@login_required
+def admin_show_unmoderated():
+    """
+    Return all the reviews on the server as HTML.
+    """
+
+    try:
+        db = get_db()
+        reviews_all = db.reviews.get_all()
+    except CursorError as e:
+        return _error_internal(str(e))
+    if not reviews_all and page != 1:
+        abort(404)
+
+    user_hash = _get_hash_for_user(current_user)
+    if not user_hash:
+        return _error_internal('no user_hash...')
+
+    # filter by the languages the moderator understands
+    reviews = []
+    langs = _get_langs_for_user(current_user)
+    for r in reviews_all:
+        lang = r.locale.split('_')[0]
+        if langs and lang not in langs:
+            continue
+        if db.reviews.vote_exists(r.review_id, user_hash):
+            continue
+        if len(reviews_all) > 20:
+            break
+        reviews.append(r)
+    return render_template('show-all.html',
+                           pagination=None,
+                           reviews=reviews)
+
 @app.route('/admin/show/reported')
 @login_required
 def admin_show_reported():
@@ -551,7 +603,7 @@ def admin_moderator_show(username):
     """
     Shows an admin panel for a moderator
     """
-    if username != current_user.username and current_user.username != 'root':
+    if username != current_user.username and current_user.username != 'admin':
         return _error_permission_denied('Unable to show moderator information')
     try:
         db = get_db()
@@ -585,13 +637,44 @@ def admin_moderate_delete(username):
     flash('Deleted user')
     return redirect(url_for('.admin_moderator_show_all'), 302)
 
+@app.route('/admin/vote/<review_id>/<val_str>')
+@login_required
+def admin_vote(review_id, val_str):
+    """ Up or downvote an existing review by @val karma points """
+    user_hash = _get_hash_for_user(current_user)
+    if not user_hash:
+        return _error_internal('no user_hash...')
+    if val_str == 'up':
+        val = 1
+    elif val_str == 'down':
+        val = -1;
+    elif val_str == 'meh':
+        val = 0;
+    else:
+        return _error_internal('invalid vote value...')
+    try:
+        # the user already has a review
+        db = get_db()
+        if db.reviews.vote_exists(review_id, user_hash):
+            flash('already voted on this app')
+            return redirect(url_for('.admin_show_review', review_id=review_id))
+        user = db.users.get_by_hash(user_hash)
+        if not user:
+            db.users.add(user_hash)
+        db.users.update_karma(user_hash, val)
+        db.reviews.vote_add(review_id, val, user_hash)
+    except CursorError as e:
+        return json_error(str(e))
+    return redirect(url_for('.admin_show_review', review_id=review_id))
+
+
 @app.route('/admin/moderator/<username>/modify_by_admin', methods=['POST'])
 @login_required
 def user_modify_by_admin(username):
     """ Change details about the any user """
 
     # security check
-    if username != current_user.username and current_user.username != 'root':
+    if username != current_user.username and current_user.username != 'admin':
         return _error_permission_denied('Unable to modify user as non-admin')
 
     # set each thing in turn


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]