aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models.py25
-rw-r--r--app/templates/base.html1
-rw-r--r--app/templates/notifications/list.html17
-rw-r--r--app/views/__init__.py2
-rw-r--r--app/views/notifications.py9
-rw-r--r--app/views/packages.py35
-rw-r--r--app/views/utils.py11
-rw-r--r--setup.py4
8 files changed, 99 insertions, 5 deletions
diff --git a/app/models.py b/app/models.py
index b4edcc2..e0bcb2e 100644
--- a/app/models.py
+++ b/app/models.py
@@ -88,8 +88,11 @@ class User(db.Model, UserMixin):
display_name = db.Column(db.String(100), nullable=False, server_default="")
# Content
- packages = db.relationship("Package", backref="author", lazy="dynamic")
- requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
+ notifications = db.relationship("Notification", primaryjoin="User.id==Notification.user_id")
+
+ # causednotifs = db.relationship("Notification", backref="causer", lazy="dynamic")
+ packages = db.relationship("Package", backref="author", lazy="dynamic")
+ requests = db.relationship("EditRequest", backref="author", lazy="dynamic")
def __init__(self, username):
import datetime
@@ -119,6 +122,24 @@ class User(db.Model, UserMixin):
else:
raise Exception("Permission {} is not related to users".format(perm.name))
+
+class Notification(db.Model):
+ id = db.Column(db.Integer, primary_key=True)
+ user_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+ causer_id = db.Column(db.Integer, db.ForeignKey("user.id"))
+ user = db.relationship("User", foreign_keys=[user_id])
+ causer = db.relationship("User", foreign_keys=[causer_id])
+
+ title = db.Column(db.String(100), nullable=False)
+ url = db.Column(db.String(200), nullable=True)
+
+ def __init__(self, us, cau, titl, ur):
+ self.user = us
+ self.causer = cau
+ self.title = titl
+ self.url = ur
+
+
class License(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(50), nullable=False, unique=True)
diff --git a/app/templates/base.html b/app/templates/base.html
index 0ab87b4..cdf1f1f 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -40,6 +40,7 @@
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
+ <li><a href="{{ url_for('notifications_page') }}">({{ current_user.notifications | length }})</a></li>
<li><a href="{{ url_for('user_profile_page', username=current_user.username) }}">{{ current_user.display_name }}</a></li>
<li><a href="{{ url_for('user.logout') }}">Sign out</a></li>
{% else %}
diff --git a/app/templates/notifications/list.html b/app/templates/notifications/list.html
new file mode 100644
index 0000000..fb133e8
--- /dev/null
+++ b/app/templates/notifications/list.html
@@ -0,0 +1,17 @@
+{% extends "base.html" %}
+
+{% block title %}
+Notifications
+{% endblock %}
+
+{% block content %}
+ <ul>
+ {% for n in current_user.notifications %}
+ <li><a href="{{ n.url }}">
+ {{ n.title}} [{{ n.causer.display_name }}]
+ </a></li>
+ {% else %}
+ <li><i>No notifications</i></ul>
+ {% endfor %}
+ </ul>
+{% endblock %}
diff --git a/app/views/__init__.py b/app/views/__init__.py
index dba81ad..22ed5ab 100644
--- a/app/views/__init__.py
+++ b/app/views/__init__.py
@@ -30,4 +30,4 @@ def home_page():
packages = Package.query.filter_by(approved=True).all()
return render_template("index.html", packages=packages)
-from . import users, githublogin, packages, sass, tasks, admin
+from . import users, githublogin, packages, sass, tasks, admin, notifications
diff --git a/app/views/notifications.py b/app/views/notifications.py
new file mode 100644
index 0000000..77108d7
--- /dev/null
+++ b/app/views/notifications.py
@@ -0,0 +1,9 @@
+from flask import *
+from flask_user import current_user, login_required
+from app import app
+from app.models import *
+
+@app.route("/notifications/")
+@login_required
+def notifications_page():
+ return render_template("notifications/list.html")
diff --git a/app/views/packages.py b/app/views/packages.py
index 96e50b4..bbebc67 100644
--- a/app/views/packages.py
+++ b/app/views/packages.py
@@ -96,6 +96,8 @@ def package_page(author, name):
if shouldReturnJson():
return jsonify(package.getAsDictionary(app.config["BASE_URL"]))
else:
+ clearNotifications(package.getDetailsURL())
+
releases = getReleases(package)
requests = [r for r in package.requests if r.status == 0]
return render_template("packages/view.html", package=package, releases=releases, requests=requests)
@@ -168,7 +170,9 @@ def create_edit_package_page(author=None, name=None):
if not package:
package = Package()
package.author = author
- # package.approved = package.checkPerm(current_user, Permission.APPROVE_NEW)
+ else:
+ triggerNotif(package.author, current_user,
+ "{} edited".format(package.title), package.getDetailsURL())
form.populate_obj(package) # copy to row
@@ -194,8 +198,10 @@ def approve_package_page(author=None, name=None):
else:
package.approved = True
- db.session.commit()
+ triggerNotif(package.author, current_user,
+ "{} approved".format(package.title), package.getDetailsURL())
+ db.session.commit()
return redirect(package.getDetailsURL())
@@ -222,6 +228,10 @@ def create_screenshot_page(author, name):
ss.title = form["title"].data
ss.url = uploadedPath
db.session.add(ss)
+
+ msg = "{}: Screenshot added {}" \
+ .format(package.title, ss.title)
+ triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@@ -292,6 +302,10 @@ def create_edit_editrequest_page(pauthor, name, id=None):
wasChangeMade = True
if wasChangeMade:
+ msg = "{}: Edit request #{} {}" \
+ .format(package.title, erequest.id, "created" if id is None else "edited")
+ triggerNotif(package.author, current_user, msg, erequest.getURL())
+ triggerNotif(erequest.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(erequest.getURL())
else:
@@ -311,6 +325,7 @@ def view_editrequest_page(pauthor, name, id):
if erequest is None:
abort(404)
+ clearNotifications(erequest.getURL())
return render_template("packages/editrequest_view.html", package=package, request=erequest)
@@ -331,6 +346,10 @@ def approve_editrequest_page(pauthor, name, id):
else:
erequest.status = 1
erequest.applyAll(package)
+
+ msg = "{}: Edit request #{} merged".format(package.title, erequest.id)
+ triggerNotif(erequest.author, current_user, msg, erequest.getURL())
+ triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@@ -351,6 +370,10 @@ def reject_editrequest_page(pauthor, name, id):
else:
erequest.status = 2
+
+ msg = "{}: Edit request #{} rejected".format(package.title, erequest.id)
+ triggerNotif(erequest.author, current_user, msg, erequest.getURL())
+ triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@@ -389,6 +412,9 @@ def create_release_page(author, name):
db.session.commit()
rel.task_id = makeVCSRelease.delay(rel.id, form["vcsLabel"].data).id
+
+ msg = "{}: Release {} created".format(package.title, rel.title)
+ triggerNotif(package.author, current_user, msg, rel.getEditURL())
db.session.commit()
return redirect(url_for("check_task", id=rel.task_id, r=package.getDetailsURL()))
@@ -400,6 +426,9 @@ def create_release_page(author, name):
rel.title = form["title"].data
rel.url = uploadedPath
db.session.add(rel)
+
+ msg = "{}: Release {} created".format(package.title, rel.title)
+ triggerNotif(package.author, current_user, msg, erequest.getURL())
db.session.commit()
return redirect(package.getDetailsURL())
@@ -420,6 +449,8 @@ def edit_release_page(author, name, id):
if package.name != name or package.author.username != author:
abort(404)
+ clearNotifications(release.getEditURL())
+
canEdit = package.checkPerm(current_user, Permission.MAKE_RELEASE)
canApprove = package.checkPerm(current_user, Permission.APPROVE_RELEASE)
if not (canEdit or canApprove):
diff --git a/app/views/utils.py b/app/views/utils.py
index f22e874..345d5c1 100644
--- a/app/views/utils.py
+++ b/app/views/utils.py
@@ -91,3 +91,14 @@ def rank_required(rank):
return decorated_function
return decorator
+
+def triggerNotif(owner, causer, title, url):
+ if owner.rank.atLeast(UserRank.NEW_MEMBER) and owner != causer:
+ Notification.query.filter_by(user=owner, url=url).delete()
+ notif = Notification(owner, causer, title, url)
+ db.session.add(notif)
+
+def clearNotifications(url):
+ if current_user.is_authenticated:
+ Notification.query.filter_by(user=current_user, url=url).delete()
+ db.session.commit()
diff --git a/setup.py b/setup.py
index 81ad254..901bbc8 100644
--- a/setup.py
+++ b/setup.py
@@ -21,12 +21,16 @@ if not os.path.isfile("db.sqlite"):
ruben.rank = UserRank.ADMIN
db.session.add(ruben)
+
ez = User("Shara")
ez.github_username = "Ezhh"
ez.forums_username = "Shara"
ez.rank = UserRank.EDITOR
db.session.add(ez)
+ not1 = Notification(ruben, ez, "Awards approved", "/packages/rubenwardy/awards/")
+ db.session.add(not1)
+
jeija = User("Jeija")
jeija.github_username = "Jeija"
db.session.add(jeija)