[odrs-web] Add taboo severity and export to JSON



commit a4fd01aff6bf8df05a2c17b4df3a2dd77fdff5a2
Author: Richard Hughes <richard hughsie com>
Date:   Thu Jul 4 09:07:58 2019 +0100

    Add taboo severity and export to JSON

 app_data/cron.py                              | 31 ++++++++++++++-------------
 app_data/migrations/versions/b2d75ba212ed_.py | 22 +++++++++++++++++++
 app_data/odrs/models.py                       | 20 ++++++++++++++++-
 app_data/odrs/templates/show.html             | 11 +++-------
 app_data/odrs/templates/taboos.html           |  5 +++++
 app_data/odrs/tests/odrs_test.py              | 19 ++++++++++++++--
 app_data/odrs/views_admin.py                  |  5 +++--
 app_data/odrs/views_api.py                    | 21 ++++++++++++++++--
 8 files changed, 104 insertions(+), 30 deletions(-)
---
diff --git a/app_data/cron.py b/app_data/cron.py
index 7eef21f..7bab12c 100755
--- a/app_data/cron.py
+++ b/app_data/cron.py
@@ -74,23 +74,24 @@ def _taboo_import(fn):
 
     # add any new ones
     with open(fn, newline='') as csvfile:
-        for locale, value, description in csv.reader(csvfile):
+        for locale, values, description, severity in csv.reader(csvfile):
             locale = locale.strip()
-            value = value.strip()
             description = description.strip()
-            key = locale + ':' + value
-            if key in taboos:
-                continue
-            if value.find(' ') != -1:
-                print('Ignoring', locale, value)
-                continue
-            if value.lower() != value:
-                print('Ignoring', locale, value)
-                continue
-            taboo = Taboo(locale, value, description)
-            taboos[key] = taboo
-            print('Adding', locale, value)
-            db.session.add(taboo)
+            for value in values.split('/'):
+                value = value.strip()
+                key = locale + ':' + value
+                if key in taboos:
+                    continue
+                if value.find(' ') != -1:
+                    print('Ignoring', locale, value)
+                    continue
+                if value.lower() != value:
+                    print('Ignoring', locale, value)
+                    continue
+                taboo = Taboo(locale, value, description, severity=int(severity))
+                taboos[key] = taboo
+                print('Adding', locale, value)
+                db.session.add(taboo)
     db.session.commit()
 
 if __name__ == '__main__':
diff --git a/app_data/migrations/versions/b2d75ba212ed_.py b/app_data/migrations/versions/b2d75ba212ed_.py
new file mode 100644
index 0000000..265cd89
--- /dev/null
+++ b/app_data/migrations/versions/b2d75ba212ed_.py
@@ -0,0 +1,22 @@
+"""
+
+Revision ID: b2d75ba212ed
+Revises: e37c745e3097
+Create Date: 2019-07-04 09:07:17.032627
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'b2d75ba212ed'
+down_revision = 'e37c745e3097'
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import mysql
+
+def upgrade():
+    op.add_column('taboos', sa.Column('severity', sa.Integer(), nullable=True))
+
+
+def downgrade():
+    op.drop_column('taboos', 'severity')
diff --git a/app_data/odrs/models.py b/app_data/odrs/models.py
index 7bb4d40..0926a72 100644
--- a/app_data/odrs/models.py
+++ b/app_data/odrs/models.py
@@ -54,11 +54,29 @@ class Taboo(db.Model):
     locale = Column(String(8), nullable=False, index=True)
     value = Column(Text, nullable=False)
     description = Column(Text, nullable=True)
+    severity = Column(Integer, default=0)
 
-    def __init__(self, locale, value, description=True):
+    def __init__(self, locale, value, description=None, severity=0):
         self.locale = locale
         self.value = value
         self.description = description
+        self.severity = severity
+
+    def asdict(self):
+        item = {'value': self.value}
+        if self.severity:
+            item['severity'] = self.severity
+        if self.description:
+            item['description'] = self.description
+        return item
+
+    @property
+    def color(self):
+        if self.severity == 3:
+            return 'danger'
+        if self.severity == 2:
+            return 'warning'
+        return 'info'
 
     def __repr__(self):
         return 'Taboo object %s' % self.taboo_id
diff --git a/app_data/odrs/templates/show.html b/app_data/odrs/templates/show.html
index cd87240..7566232 100644
--- a/app_data/odrs/templates/show.html
+++ b/app_data/odrs/templates/show.html
@@ -11,16 +11,11 @@
       {{r.app_id}}
       <a class="btn pull-right" href="{{url_for('.admin_show_app', app_id=r.app_id)}}">All</a>
     </h1>
-{% if matched_taboos %}
-    <div class="alert alert-warning" role="alert">
-      <strong>Warning: Contains taboo:</strong>
-      <ul>
 {% for taboo in matched_taboos %}
-        <li>{{taboo.value}}: {{taboo.description}}</li>
-{% endfor %}
-      </ul>
+    <div class="alert alert-{{taboo.color}}" role="alert">
+      Contains taboo <strong>{{taboo.value}}</strong> which is {{taboo.description}}
     </div>
-{% endif %}
+{% endfor %}
     <table class="table card-text table-borderless table-condensed">
       <tr class="row">
         <th class="col col-md-2">Rating</th>
diff --git a/app_data/odrs/templates/taboos.html b/app_data/odrs/templates/taboos.html
index 6097b65..32dd533 100644
--- a/app_data/odrs/templates/taboos.html
+++ b/app_data/odrs/templates/taboos.html
@@ -15,6 +15,7 @@
   <tr class="row">
     <th class="col-sm-1">Locale</th>
     <th class="col-sm-2">Value</th>
+    <th class="col-sm-1">Severity</th>
     <th class="col-sm-7">Description</th>
     <th class="col-sm-2">&nbsp;</th>
   </tr>
@@ -22,6 +23,7 @@
   <tr class="row">
     <td>{{taboo.locale}}</td>
     <td>{{taboo.value}}</td>
+    <td>{{taboo.severity}}</td>
     <td>{{taboo.description}}</td>
     <td>
       <a class="btn btn-danger btn-block" href="{{url_for('.admin_taboo_delete', 
taboo_id=taboo.taboo_id)}}">Delete</a>
@@ -35,6 +37,9 @@
     <td>
       <input type="text" class="form-control" name="value" required/>
     </td>
+    <td>
+      <input type="number" class="form-control" name="severity" required/>
+    </td>
     <td>
       <input type="text" class="form-control" name="description" required/>
     </td>
diff --git a/app_data/odrs/tests/odrs_test.py b/app_data/odrs/tests/odrs_test.py
index ccdb6b6..a595265 100644
--- a/app_data/odrs/tests/odrs_test.py
+++ b/app_data/odrs/tests/odrs_test.py
@@ -215,8 +215,8 @@ class OdrsTest(unittest.TestCase):
         rv = self.app.get('/admin/search?value=inkscape+notgoingtoexist')
         assert b'Somebody Import' in rv.data, rv.data
 
-    def _admin_taboo_add(self, locale='en', value='inkscape', description='ola!'):
-        data = {'locale': locale, 'value': value, 'description': description}
+    def _admin_taboo_add(self, locale='en', value='inkscape', description='ola!', severity=0):
+        data = {'locale': locale, 'value': value, 'description': description, 'severity': severity}
         return self.app.post('/admin/taboo/add', data=data, follow_redirects=True)
 
     def test_admin_taboo(self):
@@ -247,6 +247,21 @@ class OdrsTest(unittest.TestCase):
         rv = self.app.get('/admin/taboo/1/delete', follow_redirects=True)
         assert b'No taboo with ID' in rv.data, rv.data
 
+    def test_api_taboo(self):
+
+        # unauth
+        rv = self.app.get('/1.0/reviews/api/taboo/all')
+        assert b'{}' in rv.data, rv.data
+
+        self.login()
+        rv = self._admin_taboo_add()
+        assert b'Added taboo' in rv.data, rv.data
+        self.logout()
+
+        # unauth
+        rv = self.app.get('/1.0/reviews/api/taboo/all')
+        assert b'inkscape' in rv.data, rv.data
+
     def test_api_submit_when_banned(self):
 
         # submit abusive review
diff --git a/app_data/odrs/views_admin.py b/app_data/odrs/views_admin.py
index 551d105..8dd6418 100644
--- a/app_data/odrs/views_admin.py
+++ b/app_data/odrs/views_admin.py
@@ -659,7 +659,7 @@ def admin_taboo_add():
         flash('Unable to add taboo as non-admin', 'error')
         return redirect(url_for('.odrs_index'))
 
-    for key in ['locale', 'value', 'description']:
+    for key in ['locale', 'value', 'description', 'severity']:
         if not key in request.form:
             flash('Unable to add taboo as {} missing'.format(key), 'error')
             return redirect(url_for('.odrs_index'))
@@ -672,7 +672,8 @@ def admin_taboo_add():
     # verify username
     db.session.add(Taboo(request.form['locale'],
                          request.form['value'],
-                         request.form['description']))
+                         request.form['description'],
+                         int(request.form['severity'])))
     db.session.commit()
     flash('Added taboo')
     return redirect(url_for('.admin_taboo_show_all'))
diff --git a/app_data/odrs/views_api.py b/app_data/odrs/views_api.py
index cfc4796..ad511cf 100644
--- a/app_data/odrs/views_api.py
+++ b/app_data/odrs/views_api.py
@@ -11,6 +11,8 @@ import json
 import math
 import datetime
 
+from collections import defaultdict
+
 from sqlalchemy.dialects.mysql import insert
 from sqlalchemy.exc import IntegrityError
 
@@ -18,7 +20,7 @@ from flask import request, Response
 
 from odrs import app, db
 
-from .models import Review, User, Vote, Analytic
+from .models import Review, User, Vote, Analytic, Taboo
 from .models import _vote_exists
 from .util import json_success, json_error, _locale_is_compatible, _eventlog_add, _get_user_key, 
_get_datestr_from_dt
 from .util import _sanitised_version, _sanitised_summary, _sanitised_description, _get_rating_for_app_id
@@ -436,7 +438,22 @@ def api_rating_for_id(app_id):
     Get the star ratings for a specific application.
     """
     ratings = _get_rating_for_app_id(app_id)
-    dat = json.dumps(ratings, sort_keys=True, indent=4, separators=(',', ': '))
+    dat = json.dumps(ratings, ensure_ascii=False, sort_keys=True, indent=4, separators=(',', ': '))
+    return Response(response=dat,
+                    status=200, \
+                    mimetype='application/json')
+
+@app.route('/1.0/reviews/api/taboo/all')
+def api_taboo_all():
+    """
+    Get the star ratings for a specific application.
+    """
+    items = defaultdict(list)
+    for taboo in db.session.query(Taboo).\
+                order_by(Taboo.locale.asc()).\
+                order_by(Taboo.value.asc()).all():
+        items[taboo.locale].append(taboo.asdict())
+    dat = json.dumps(items, sort_keys=True, indent=4, separators=(',', ': '))
     return Response(response=dat,
                     status=200, \
                     mimetype='application/json')


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