jenkins-bot has submitted this change and it was merged.

Change subject: Let users star and unstar queries
......................................................................


Let users star and unstar queries

- Displays starred queries info in User profile page
- Adds new star table

Change-Id: If5e976522969e7d6d43569f108c212b76c43eff0
---
M quarry/web/app.py
A quarry/web/models/star.py
M quarry/web/static/css/query/view.css
M quarry/web/static/css/user.css
M quarry/web/static/js/query/view.js
M quarry/web/templates/query/view.html
M quarry/web/templates/user.html
M tables.sql
8 files changed, 164 insertions(+), 12 deletions(-)

Approvals:
  Yuvipanda: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/quarry/web/app.py b/quarry/web/app.py
index 64a371e..c57b71c 100644
--- a/quarry/web/app.py
+++ b/quarry/web/app.py
@@ -4,12 +4,13 @@
 from models.query import Query
 from models.queryrevision import QueryRevision
 from models.queryrun import QueryRun
+from models.star import Star
 import json
 import yaml
 import time
 import os
 from sqlalchemy import desc, func
-from sqlalchemy.orm import sessionmaker
+from sqlalchemy.orm import sessionmaker, joinedload
 from redissession import RedisSessionInterface
 from mwoauth import ConsumerToken, Handshaker
 from connections import Connections
@@ -99,19 +100,67 @@
     user_name = user_name.replace('_', ' ').lower()
     user = g.session.query(User).filter(func.lower(User.username) == 
user_name).one()
     stats = {
-        'query_count': 
g.session.query(func.count(Query.id)).filter(Query.user_id == user.id).scalar()
+        'query_count': 
g.session.query(func.count(Query.id)).filter(Query.user_id == user.id).scalar(),
+        'stars_count': 
g.session.query(func.count(Star.id)).filter(Star.user_id == user.id).scalar()
     }
     recent_queries = g.session.query(Query)\
         .filter(Query.user_id == user.id)\
         .order_by(desc(Query.last_touched))\
+        .limit(10)
+    self_stars = g.session.query(Star).join(Star.query)\
+        .options(joinedload(Star.query))\
+        .filter(Star.user_id == user.id)\
+        .filter(Query.user_id == user.id)\
+        .order_by(desc(Star.timestamp))\
+        .limit(10)
+    other_stars = g.session.query(Star).join(Star.query) \
+        .options(joinedload(Star.query))\
+        .filter(Star.user_id == user.id) \
+        .filter(Query.user_id != user.id) \
+        .order_by(desc(Star.timestamp))\
         .limit(10)
     return render_template(
         "user.html",
         display_user=user,
         user=g.user,
         stats=stats,
-        recent_queries=recent_queries
+        recent_queries=recent_queries,
+        self_stars=self_stars,
+        other_stars=other_stars
     )
+
+
+@app.route("/api/query/unstar", methods=["POST"])
+def unstar_query():
+    if g.user is None:
+        return "Unauthorized access", 403
+    query = g.session.query(Query).get(request.form['query_id'])
+    if query:
+        star = g.session.query(Star)\
+            .filter(Star.query_id == request.form['query_id'])\
+            .filter(Star.user_id == g.user.id)\
+            .one()
+        g.session.delete(star)
+        g.session.commit()
+        return ""
+    else:
+        return "Query not found", 404
+
+
+@app.route("/api/query/star", methods=["POST"])
+def star_query():
+    if g.user is None:
+        return "Unauthorized access", 403
+    query = g.session.query(Query).get(request.form['query_id'])
+    if query:
+        star = Star()
+        star.user = g.user
+        star.query = query
+        g.session.add(star)
+        g.session.commit()
+        return ""
+    else:
+        return "Query not found", 404
 
 
 @app.route("/query/new")
@@ -136,9 +185,15 @@
 def query_show(query_id):
     query = g.session.query(Query).filter(Query.id == query_id).one()
     can_edit = g.user is not None and g.user.id == query.user_id
+    is_starred = False
+    if g.user:
+        is_starred = g.session.query(func.count(Star.id))\
+            .filter(Star.user_id == g.user.id)\
+            .filter(Star.query_id == query_id).scalar() == 1
     jsvars = {
         'query_id': query.id,
-        'can_edit': can_edit
+        'can_edit': can_edit,
+        'is_starred': is_starred
     }
 
     if query.latest_rev and query.latest_rev.latest_run:
diff --git a/quarry/web/models/star.py b/quarry/web/models/star.py
new file mode 100644
index 0000000..ff93654
--- /dev/null
+++ b/quarry/web/models/star.py
@@ -0,0 +1,15 @@
+from sqlalchemy import Column, Integer, ForeignKey, DateTime
+from sqlalchemy.orm import relationship
+from base import Base
+
+
+class Star(Base):
+    __tablename__ = 'star'
+
+    id = Column(Integer, primary_key=True)
+    user_id = Column(Integer, ForeignKey('user.id'))
+    timestamp = Column(DateTime)
+    query_id = Column(Integer, ForeignKey('query.id'))
+
+    query = relationship('Query', uselist=False)
+    user = relationship('User', uselist=False)
diff --git a/quarry/web/static/css/query/view.css 
b/quarry/web/static/css/query/view.css
index 0f6c648..4ef0d85 100644
--- a/quarry/web/static/css/query/view.css
+++ b/quarry/web/static/css/query/view.css
@@ -2,6 +2,23 @@
     margin-top: 20px;
 }
 
+.starred .only-starred {
+    display: block;
+}
+
+.starred .only-non-starred {
+    display: none;
+}
+
+.only-starred {
+    display: none;
+}
+
+#title-actions-container button {
+    margin-top: 18px;
+    float: right;
+}
+
 .CodeMirror {
     font-family: Monaco, Consolas, "Ubuntu Mono", monospace;
     height: auto;
diff --git a/quarry/web/static/css/user.css b/quarry/web/static/css/user.css
index 3bba155..65f1688 100644
--- a/quarry/web/static/css/user.css
+++ b/quarry/web/static/css/user.css
@@ -8,15 +8,15 @@
     padding-bottom: 12px;
 }
 
-#query-items-list {
+.query-items-list {
     list-style: none;
     padding-left: 0;
 }
 
-#query-items-list li {
+.query-items-list li {
     padding: 4px 0px;
 }
 
-#query-items-list li a.query-title {
+.query-items-list li a.query-title {
     font-size: 1.2em;
 }
diff --git a/quarry/web/static/js/query/view.js 
b/quarry/web/static/js/query/view.js
index 0de44d1..7223f99 100644
--- a/quarry/web/static/js/query/view.js
+++ b/quarry/web/static/js/query/view.js
@@ -20,6 +20,22 @@
         } );
     }
 
+    $("#un-star-query").click( function() {
+        $.post( "/api/query/unstar", {
+            query_id: vars.query_id
+        }).done(function( data ) {
+            $('#content').removeClass('starred');
+        });
+    });
+
+    $("#star-query").click( function() {
+        $.post( "/api/query/star", {
+            query_id: vars.query_id
+        }).done(function( data ) {
+            $('#content').addClass('starred');
+        });
+    });
+
     $('#run-code').click( function() {
         $.post( "/api/query/run", {
             text: editor.getValue(),
diff --git a/quarry/web/templates/query/view.html 
b/quarry/web/templates/query/view.html
index b902d29..4331500 100644
--- a/quarry/web/templates/query/view.html
+++ b/quarry/web/templates/query/view.html
@@ -12,11 +12,23 @@
 <script src="/static/js/query/view.js"> </script>
 {% endblock %}
 {% block content %}
-<div id="content" class="container {% if jsvars.can_edit %}edit{% else 
%}no-edit{% endif %}">
+<div id="content" class="container {% if jsvars.can_edit %}edit{% else 
%}no-edit{% endif %} {% if jsvars.is_starred %}starred{% endif %}">
     <div class="row" id="title-container">
-        <h2 id='title'>{{query.title}}</h2>
+        <div class="col-md-10">
+            <h2 id='title'>{{query.title}}</h2>
+        </div>
+        <div class="col-md-2" id="title-actions-container">
+            {% if user %}
+                <button id="un-star-query" type="button" class="btn btn-info 
btn-sm only-starred">
+                    <span class="glyphicon glyphicon-star"></span> Unstar
+                </button>
+                <button id="star-query" type="button" class="btn btn-info 
btn-sm only-non-starred">
+                    <span class="glyphicon glyphicon-star-empty"></span> Star
+                </button>
+            {% endif %}
+        </div>
     </div>
-    <div class="row">
+    <div>
         <h3>SQL</h3>
         <textarea id="code">{% if latest_rev %}{{ latest_rev.text 
}}{%endif%}</textarea>
     </div>
diff --git a/quarry/web/templates/user.html b/quarry/web/templates/user.html
index 3fc7b58..c66848d 100644
--- a/quarry/web/templates/user.html
+++ b/quarry/web/templates/user.html
@@ -17,14 +17,42 @@
             </div>
         </div>
     </div>
-    <div class="query-list-container">
+    <div class="row">
+        <div class="col-md-6 query-list-container">
+            <h3>Self starred Queries</h3>
+            <ul class="query-items-list">
+                {% for star in self_stars %}
+                <li class="query-item">
+                    <a class="query-title" 
href="/query/{{star.query.id}}">{{star.query.title}}</a>
+                </li>
+                {% else %}
+                    This user has not starred any of his queries yet.
+                {% endfor %}
+            </ul>
+        </div>
+        <div class="col-md-6 query-list-container">
+            <h3>Other starred Queries</h3>
+            <ul class="query-items-list">
+                {% for star in other_stars %}
+                <li class="query-item">
+                    <a class="query-title" 
href="/query/{{star.query.id}}">{{star.query.title}}</a>
+                </li>
+                {% else %}
+                    This user has not starred any other user's queries yet.
+                {% endfor %}
+            </ul>
+        </div>
+    </div>
+    <div>
         <h3>Recent Queries</h3>
-        <ul id="query-items-list">
+        <ul class="query-items-list">
             {% for query in recent_queries %}
             <li class="query-item">
                 <a class="query-title" 
href="/query/{{query.id}}">{{query.title}}</a>
                 <small>{{query.last_touched|timesince}}</small>
             </li>
+            {% else %}
+                This user has not run any queries yet
             {% endfor %}
         </ul>
     </div>
diff --git a/tables.sql b/tables.sql
index cccc846..e796094 100644
--- a/tables.sql
+++ b/tables.sql
@@ -35,3 +35,12 @@
     task_id VARCHAR(36) BINARY
 );
 CREATE INDEX query_run_status_index ON query_run(status);
+
+CREATE TABLE star(
+    id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
+    user_id INT UNSIGNED NOT NULL,
+    query_id INT UNSIGNED NOT NULL,
+    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
+CREATE INDEX star_user_id_index ON star(user_id);
+CREATE INDEX star_query_id_index ON star(query_id);

-- 
To view, visit https://gerrit.wikimedia.org/r/153963
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: If5e976522969e7d6d43569f108c212b76c43eff0
Gerrit-PatchSet: 4
Gerrit-Project: analytics/quarry/web
Gerrit-Branch: master
Gerrit-Owner: Yuvipanda <yuvipa...@gmail.com>
Gerrit-Reviewer: Springle <sprin...@wikimedia.org>
Gerrit-Reviewer: Yuvipanda <yuvipa...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to